• Django Rest Framework


    什么是Restful
    REST代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”。
    REST从资源的角度类审视整个网络,将分布的网络中某个节点的资源通过URL进行标识,客户端应用通过URL来获取资源的表征,获得这些表征只是这些应用转变状态。
    所有的数据,无论是通过网络获取的还是操作(增删改查)的数据,都是资源,将一切数据视为资源是REST区别其他架构风格的最本质属性。
    对于REST这种面向资源的架构风格,即:面向资源架构(ROA:Resource Oriented Architecture)。

    Restful API设计规范
      -API与用户的通信协议,总是使用HTTPs协议
      -域名
        应该尽量将API部署在专用域名之下,如:https://api.example.com
        如果确定API很简单也可以放在主域名下:https://example.org/api/
      -版本
        应将API的版本号放入URL
        https://api.example.com/v1/
        方法有很多,可将版本号放在HTTP头信息中,但不如放入URL方便和直观
      -路径 网络上的任何东西都是资源,均使用名词表示(可复数)
        https://api.example.com/v1/zoos
        https://api.example.com/v1/animals
      -HTTP动词
        对资源的具体操作类型,有HTTP动词表示,常用的HTTP动词有下面五种(括号为sql命令)
        GET (SELECT):从服务器取出资源(一项或多项)
        POST (CREATE):在服务器新建一个资源
        PUT (UPDATE):在服务器更新资源(客户端提供改变后的完整资源)
        PATCH (UPDATE):在服务器更新资源(客户端提供改变的属性)
        DELETE (DELETE):从服务器删除资源
        下面是一些例子。
        GET /zoos:列出所有动物园
        POST /zoos:新建一个动物园
        GET /zoos/ID:获取某个指定动物园的信息
        PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)
        PATCH /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息)
        DELETE /zoos/ID:删除某个动物园
        GET /zoos/ID/animals:列出某个指定动物园的所有动物
        DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物
      -过滤 如果记录数据很多,服务器不可能将它们返回给用户,API应提供参数过滤返回
        https://api.example.com/v1/zoos?limit=10:指定返回记录的数量
        https://api.example.com/v1/zoos?offset=10:指定返回记录的开始位置
        https://api.example.com/v1/zoos?page=2&per_page=100:指定第几页,以及每页的记录数
        https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序
        https://api.example.com/v1/zoos?animal_type_id=1:指定筛选条件
        参数的设计允许存在冗余,即允许API路径和URL参数偶尔有重复。比如,GET /zoo/ID/animals 与 GET /animals?zoo_id=ID 的含义是相同的
      -状态码 服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的HTTP动词)。
        200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
        201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
        202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
        204 NO CONTENT - [DELETE]:用户删除数据成功。
        400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
        401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
        403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
        404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
        406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
        410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
        422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
        500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

      -错误处理
        {
          code:123456,
          error:"error info"
        }
      -返回结果 针对不同操作,服务器向用户返回的结果应符合以下规范
        GET /collection:返回资源对象的列表(数组)
        GET /collection/resource:返回单个资源对象
        POST /collection:返回新生成的资源对象
        PUT /collection/resource:返回完整的资源对象
        PATCH /collection/resource:返回完整的资源对象
        DELETE /collection/resource:返回一个空文档
      -Hypermedia API
        RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。
        比如,当用户向api.example.com的根目录发出请求,会得到这样一个文档。
        {"link": {
          "rel": "collection https://www.example.com/zoos",
          "href": "https://api.example.com/zoos",
          "title": "List of zoos",
          "type": "application/vnd.yourformat+json"
        }}

    基于Django实现

     1 路由系统
     2     urlpatterns = [
     3         url(r'^users', Users.as_view()),
     4     ]
     5 CBV视图
     6     from django.views import View
     7     from django.http import JsonResponse
     8      
     9     class Users(View):
    10         def get(self, request, *args, **kwargs):
    11             result = {
    12                 'status': True,
    13                 'data': 'response data'
    14             }
    15             return JsonResponse(result, status=200)
    16      
    17         def post(self, request, *args, **kwargs):
    18             result = {
    19                 'status': True,
    20                 'data': 'response data'
    21             }
    22             return JsonResponse(result, status=200)

    基于Django Rest Framework框架实现

    1.序列化

    自定义序列化类

    1 from rest_framework import serializers
    2     class PublishSerializers(serializers.Serializer):
    3         name = serializers.CharField()
    4         email = serializers.CharField()

    自定义外键关联序列化类

     1      class BookSerializers(serializers.Serializer):
     2          title = serializers.CharField(max_length=32)
     3          price = serializers.IntegerField()
     4          pub_date = serializers.DateField()
     5          publish=serializers.CharField(source="publish.name")#一对多字段
     6          #authors=serializers.CharField(source="authors.all")
     7          authors = serializers.SerializerMethodField()#多对多字段
     8          def get_authors(self,obj):#get_authors return的数据就是返回的json中authors值
     9              temp=[]
    10              for obj in obj.authors.all():
    11                  temp.append(obj.name)
    12              return temp
    13     # '''
    14     # 序列化BookSerializers(book_list,many=True)过程:
    15     #      temp=[]
    16     #      for obj in book_list:
    17     #          temp.append({
    18     #             "title":obj.title,
    19     #             "price":obj.price,
    20     #             "pub_date":obj.pub_date,
    21     #             "publish":str(obj.publish), # obj.publish.name
    22     #             #"authors":obj.authors.all,
    23     #             "authors": get_authors(obj)
    24     #          })
    25     # '''

    view

     1     class PublishView(APIView):
     2         def get(self,request):
     3             '''序列化'''
     4             # 方式1:queryset对象通过list()转换成json对象
     5             # publish_list=list(Publish.objects.all().values("name","email"))
     6             # return HttpResponse(json.dumps(publish_list))
     7 
     8             # 方式2:model_to_dict把一个model对象转换成字段的方法
     9             # from django.forms.models import model_to_dict
    10             # publish_list=Publish.objects.all()
    11             # temp=[]
    12             # for obj in publish_list:
    13             #     temp.append(model_to_dict(obj))
    14             # return HttpResponse(json.dumps(temp))
    15 
    16             # 方式3:通过Django的序列化组件serializers(和rest_framework没关系)
    17             # from django.core import serializers
    18             # publish_list=Publish.objects.all()
    19             # ret=serializers.serialize("json",publish_list)
    20             # return HttpResponse(ret)
    21 
    22             # 方式4 rest_framework对queryset和model对象序列化(通过自定义序列化类实现)
    23             publish_list = Publish.objects.all()
    24             ps = PublishSerializers(publish_list, many=True)
    25             # many=True 声明是queryset多条数据,默认many=Flase
    26             return HttpResponse(ps.data)
    27 
    28         def post(self,request):
    29             print("request.data",request.data)
    30             return HttpResponse("POST")
    View Code

    单条数据序列化

     1 路由部分
     2     urlpatterns = [
     3         path('books/',views.BookView.as_view(),name="books"),
     4         re_path(r'^books/(d+)/$',views.BookDetailView.as_view(),name="detailbook"),
     5     ]
     6     视图部分
     7     class BookModelSerializers(serializers.ModelSerializer):
     8         class Meta:
     9             model = Book
    10             fields = "__all__"
    11         
    12         #HyperlinkedIdentityField属性 获取对应的链接地址 {"publish": "http://127.0.0.1:8000/publishes/3/"}
    13         #view_name 通过函数的name获取url lookup_field 传入的id  lookup_url_kwarg id替换的位置
    14         publish = serializers.HyperlinkedIdentityField(
    15             view_name="detailpublish",
    16             lookup_field="publish_id",
    17             lookup_url_kwarg="pk"
    18         )
    19         
    20     class BookDetailView(APIView):
    21     # 单条数据操作
    22     def get(self,request,id):
    23         book=Book.objects.filter(pk=id).first()
    24         bs=BookModelSerializers(book)#model对象不用加many
    25         return Response(bs.data)
    26     def put(self,request,id):
    27         book=Book.objects.filter(pk=id).first()
    28         bs=BookModelSerializers(book,data=request.data,context={'request': request})
    29         #序列化类传入model对象和前端提交的数据
    30         #序列化类可以双向数据转换
    31         if bs.is_valid():
    32             bs.save()
    33             return Response(bs.data)
    34         else:
    35             return Response(bs.errors)
    36     def delete(self,request,id):
    37         Book.objects.filter(pk=id).delete()
    38         return Response()
    View Code

    视图mixins

     1 路由部分
     2         urlpatterns = [
     3             path('authors/',views.AuthorView.as_view(),name="author"),
     4             re_path(r'^authors/(?P<pk>d+)/$',views.AuthorDetailView.as_view(),name="detailauthor"),
     5         ]
     6         
     7         视图部分
     8         class AuthorModelSerializers(serializers.ModelSerializer):
     9             class Meta:
    10                 model = Author
    11                 fields = "__all__"
    12         一.
    13         # from rest_framework import mixins
    14         # from rest_framework import generics
    15         # class AuthorView(mixins.ListModelMixin,mixins.CreateModelMixin,generics.GenericAPIView):
    16         #     #指定queryset,serializers为queryset对象和序列画的类,且名称固定
    17         #     queryset=Author.objects.all()
    18         #     serializer_class=AuthorModelSerializers
    19         #
    20         #     def get(self,request,*args,**kwargs):
    21         #         return self.list(request,*args,**kwargs)
    22         #     def post(self,request,*args,**kwargs):
    23         #         return self.create(request,*args,**kwargs)
    24         #
    25         #
    26         # class AuthorDetailView(mixins.RetrieveModelMixin, mixins.DestroyModelMixin, mixins.UpdateModelMixin,
    27         #                        generics.GenericAPIView):
    28         #     queryset = Author.objects.all()
    29         #     serializer_class = AuthorModelSerializers
    30         #     def get(self, request, *args, **kwargs):
    31         #         return self.retrieve(request,*args,**kwargs)
    32         #     def delete(self,request,*args,**kwargs):
    33         #         return self.destroy(request,*args,**kwargs)
    34         #     def put(self,request,*args,**kwargs):
    35         #         return self.retrieve(request,*args,**kwargs)
    36         二.对上面的进一步封装
    37         # from rest_framework import mixins
    38         # from rest_framework import generics
    39         #
    40         # class AuthorView(generics.ListCreateAPIView):
    41         #     queryset=Author.objects.all()
    42         #     serializer_class =AuthorModelSerializers
    43         #
    44         # class AuthorDetailView(generics.RetrieveUpdateDestroyAPIView):
    45         #     queryset = Author.objects.all()
    46         #     serializer_class = AuthorModelSerializers
    47 viewsets(更进一步的封装)
    48     
    49     路由部分
    50     urlpatterns = [
    51         path('authors/',views.AuthorModelView.as_view({"get":"list","post":"create"}),name="author"),
    52         re_path(r'^authors/(?P<pk>d+)/$',views.AuthorModelView.as_view({"get":"retrieve","put":"update","delete":"destroy"}),name="detailauthor"),
    53     ]
    54     
    55     视图部分
    56     class AuthorModelSerializers(serializers.ModelSerializer):
    57         class Meta:
    58             model = Author
    59             fields = "__all__"
    60     
    61     from rest_framework import viewsets
    62 
    63     class AuthorModelView(viewsets.ModelViewSet):
    64         queryset = Author.objects.all()
    65         serializer_class = AuthorModelSerializers
    66 
    67     # def list(self,request,*args,**kwargs):
    68     #     #自定义方法
    69     #     pass
    View Code

    2.登录

     1 #用户登录成功会创建或更新token值
     2     def get_random_str(user):
     3         #根据用户名和时间返回随机字token值
     4         import hashlib,time
     5         ctime=str(time.time())
     6         md5=hashlib.md5(bytes(user,encoding="utf8"))
     7         md5.update(bytes(ctime,encoding="utf8"))
     8         return md5.hexdigest()
     9 
    10     class LoginView(APIView):
    11         def post(self,request):
    12             name=request.data.get("name")
    13             pwd=request.data.get("pwd")
    14             user=User.objects.filter(name=name,pwd=pwd).first()
    15             res = {"state_code":1000,"msg":None}
    16             if user:
    17                 random_str=get_random_str(user.name)
    18                 Token.objects.update_or_create(user=user,defaults={"token":random_str})
    19                 res["token"]=random_str
    20             else:
    21                 res["state_code"]=1001
    22                 res["msg"]="用户名密码错误"
    23             return Response(json.dumps(res,ensure_ascii=False))

    3.权限组件

     1 #自定义认证类
     2     from rest_framework import exceptions
     3     from rest_framework.authentication import BaseAuthentication
     4     class TokenAuth(BaseAuthentication):
     5         def authenticate(self,request):
     6             token = request.GET.get("token")
     7             token_obj = Token.objects.filter(token=token).first()
     8             if not token_obj:
     9                 raise exceptions.AuthenticationFailed("验证失败123!")
    10             else:
    11                 return token_obj.user.name,token_obj.token
    12 
    13         #继承了BaseAuthentication所有下面可以注释
    14         # def authenticate_header(self, request):
    15         #     pass
    16     
    17     #局部认证
    18     class BookView(APIView):
    19         authentication_classes = [TokenAuth,]
    20     
    21     #全局认证
    22     setting.py
    23     
    24     REST_FRAMEWORK = {
    25         "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.TokenAuth",]# 全局认证 TokenAuth路径
    26     }

    4.权限组件

     1 model
     2     class User(models.Model):
     3         name=models.CharField(max_length=32)
     4         pwd=models.CharField(max_length=32)
     5         type_choices=((1,"普通用户"),(2,"VIP"),(3,"SVIP"))
     6         user_type=models.IntegerField(choices=type_choices,default=1)
     7         
     8     自定义权限类
     9     class SVIPPermission(object):
    10     message="只有超级用户才能访问"#自定义返回信息
    11     def has_permission(self,request,view):
    12         username=request.user
    13         token = request.auth
    14         #print(username,token)认证组件的返回值为 user.name , token 
    15         user_type=User.objects.filter(name=username).first().user_type
    16 
    17         if user_type==3:
    18 
    19             return True # 通过权限认证
    20         else:
    21             return False
    22     
    23     局部权限
    24     views
    25     class BookView(APIView):
    26         authentication_classes = [TokenAuth,]#认证
    27         permission_classes = [SVIPPermission, ]#权限
    28     全局权限
    29     setting.py
    30     REST_FRAMEWORK = {
    31         "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.TokenAuth",]# 全局认证 TokenAuth路径
    32         "DEFAULT_PERMISSION_CLASSES": ["app01.utils.SVIPPermission",],#全局权限
    33     }

    5.频率组件

    局部频率限制限制

     1 rom rest_framework.throttling import BaseThrottle
     2 
     3     VISIT_RECORD={}
     4     class VisitThrottle(BaseThrottle):
     5 
     6         def __init__(self):
     7             self.history=None
     8 
     9         def allow_request(self,request,view):
    10             remote_addr = request.META.get('REMOTE_ADDR')
    11             print(remote_addr)
    12             import time
    13             ctime=time.time()
    14 
    15             if remote_addr not in VISIT_RECORD:
    16                 VISIT_RECORD[remote_addr]=[ctime,]
    17                 return True
    18 
    19             history=VISIT_RECORD.get(remote_addr)
    20             self.history=history
    21 
    22             while history and history[-1]<ctime-60:
    23                 history.pop()
    24 
    25             if len(history)<3:
    26                 history.insert(0,ctime)
    27                 return True
    28             else:
    29                 return False
    30 
    31         def wait(self):
    32             import time
    33             ctime=time.time()
    34             return 60-(ctime-self.history[-1])
    35     
    36     
    37     from app01.service.throttles import *
    38 
    39         class BookViewSet(generics.ListCreateAPIView):
    40             throttle_classes = [VisitThrottle,]
    View Code

    全局频率限制

     1 频率限制类
     2     class VisitThrottle(SimpleRateThrottle):
     3         scope="visit_rate"
     4         def get_cache_key(self, request, view):
     5             return self.get_ident(request)
     6     
     7     setting.py
     8     REST_FRAMEWORK={
     9         "DEFAULT_THROTTLE_CLASSES":["app01.service.throttles.VisitThrottle",],
    10         "DEFAULT_THROTTLE_RATES":{
    11             "visit_rate":"5/m",
    12         }
    13     }
    View Code

    6.解析器 

     1 局部解析
     2     from rest_framework.parsers import JSONParser,FormParser,MultiPartParser,FileUploadParser
     3     class BookView(APIView):
     4         #parser_classes = [FormParser,]#解析器(默认JSONParser,FormParser,MultiPartParser)
     5     
     6     全局解析
     7     REST_FRAMEWORK = {
     8         #定义全局解析
     9         # 'DEFAULT_PARSER_CLASSES': [ 
    10         #     'rest_framework.parsers.JSONParser'
    11         #     'rest_framework.parsers.FormParser'
    12         #     'rest_framework.parsers.MultiPartParser'
    13         # ]
    14     }
    15     
    16     仅上传文件
    17     url
    18     from django.conf.urls import url, include
    19     from web.views import TestView
    20 
    21     urlpatterns = [
    22         url(r'test/(?P<filename>[^/]+)', TestView.as_view(), name='test'),
    23     ]
    24     
    25     views
    26     from rest_framework.views import APIView
    27     from rest_framework.response import Response
    28     from rest_framework.request import Request
    29     from rest_framework.parsers import FileUploadParser
    30 
    31 
    32     class TestView(APIView):
    33         parser_classes = [FileUploadParser, ]
    34 
    35         def post(self, request, filename, *args, **kwargs):
    36             print(filename)
    37             print(request.content_type)
    38 
    39             # 获取请求的值,并使用对应的JSONParser进行处理
    40             print(request.data)
    41             # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
    42             print(request.POST)
    43             print(request.FILES)
    44             return Response('POST请求,响应内容')
    45 
    46         def put(self, request, *args, **kwargs):
    47             return Response('PUT请求,响应内容')    
    48 
    49     template
    50     <!DOCTYPE html>
    51     <html lang="en">
    52     <head>
    53         <meta charset="UTF-8">
    54         <title>Title</title>
    55     </head>
    56     <body>
    57     <form action="http://127.0.0.1:8000/test/f1.numbers" method="post" enctype="multipart/form-data">
    58         <input type="text" name="user" />
    59         <input type="file" name="img">
    60 
    61         <input type="submit" value="提交">
    62 
    63     </form>
    64     </body>
    65     </html>
    View Code

    7.url路由控制

    自定义路由

     1 from django.conf.urls import url, include
     2     from web.views import s11_render
     3     urlpatterns = [
     4         url(r'^test/$', s11_render.TestView.as_view()),
     5         url(r'^test.(?P<format>[a-z0-9]+)$', s11_render.TestView.as_view()),
     6         url(r'^test/(?P<pk>[^/.]+)/$', s11_render.TestView.as_view()),
     7         url(r'^test/(?P<pk>[^/.]+).(?P<format>[a-z0-9]+)$', s11_render.TestView.as_view())
     8     ]
     9     
    10     from rest_framework.views import APIView
    11     from rest_framework.response import Response
    12     from .. import models
    13     class TestView(APIView):
    14         def get(self, request, *args, **kwargs):
    15             print(kwargs)
    16             print(self.renderer_classes)
    17             return Response('...')
    View Code

    半自动路由

     1 from django.conf.urls import url, include
     2     from web.views import s10_generic
     3 
     4     urlpatterns = [
     5         url(r'^test/$', s10_generic.UserViewSet.as_view({'get': 'list', 'post': 'create'})),
     6         url(r'^test/(?P<pk>d+)/$', s10_generic.UserViewSet.as_view(
     7             {'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'})),
     8     ]
     9 
    10     from rest_framework.viewsets import ModelViewSet
    11     from rest_framework import serializers
    12     from .. import models
    13 
    14     class UserSerializer(serializers.ModelSerializer):
    15         class Meta:
    16             model = models.UserInfo
    17             fields = "__all__"
    18 
    19     class UserViewSet(ModelViewSet):
    20         queryset = models.UserInfo.objects.all()
    21         serializer_class = UserSerializer
    View Code

    全自动路由

     1 from django.conf.urls import url, include
     2     from rest_framework import routers
     3     from web.views import s10_generic
     4 
     5 
     6     router = routers.DefaultRouter()
     7     router.register(r'users', s10_generic.UserViewSet)
     8 
     9     urlpatterns = [
    10         url(r'^', include(router.urls)),
    11     ]
    12 
    13     from rest_framework.viewsets import ModelViewSet
    14     from rest_framework import serializers
    15     from .. import models
    16 
    17 
    18     class UserSerializer(serializers.ModelSerializer):
    19         class Meta:
    20             model = models.UserInfo
    21             fields = "__all__"
    22 
    23 
    24     class UserViewSet(ModelViewSet):
    25         queryset = models.UserInfo.objects.all()
    26         serializer_class = UserSerializer
    View Code

    8.分页组件(可在setting全局配置)

    根据页码进行分页

     1 from rest_framework.pagination import PageNumberPagination
     2     class ResultsPagination(PageNumberPagination):
     3         page_size = 2 #默认每页显示多少条数据
     4         page_size_query_param = "page_size" #获取URL参数设置的每页显示数据条数
     5         page_query_param = "page" #获取URL参数中传入的页码
     6         max_page_size = 1 #最大支持的每页显示的数据条数
     7 
     8     class BookView(APIView):
     9         def get(self,request):
    10             book_list=Book.objects.all()
    11             # 实例化分页对象,获取数据库中的分页数据
    12             paginator = ResultsPagination()
    13             page_user_list = paginator.paginate_queryset(book_list,request,self)
    14             #把实例化得数据传入序列化组件
    15             bs=BookModelSerializers(page_user_list,many=True,context={'request': request})
    16             return Response(bs.data)
    View Code

    根据位置和个数进行分页

     1 from rest_framework.pagination import LimiOffsetPagination
     2     class ResultsPagination(LimitOffsetPagination):
     3         # 默认每页显示的数据条数
     4         default_limit = 10
     5         # URL中传入的显示数据条数的参数
     6         limit_query_param = 'limit'
     7         # URL中传入的数据位置的参数
     8         offset_query_param = 'offset'
     9         # 最大每页显得条数
    10         max_limit = None
    11     
    12     class BookView(APIView):
    13         def get(self,request):
    14             book_list=Book.objects.all()
    15             # 实例化分页对象,获取数据库中的分页数据
    16             paginator = ResultsPagination()
    17             page_user_list = paginator.paginate_queryset(book_list,request,self)
    18             #把实例化得数据传入序列化组件
    19             bs=BookModelSerializers(page_user_list,many=True,context={'request': request})
    20             return Response(bs.data)
    View Code

    9.版本

    基于url的get传参方式

     1 REST_FRAMEWORK = {
     2         'DEFAULT_VERSION': 'v1',            # 默认版本
     3         'ALLOWED_VERSIONS': ['v1', 'v2'],   # 允许的版本
     4         'VERSION_PARAM': 'version'          # URL中获取值的key
     5     }
     6     
     7     from django.conf.urls import url, include
     8     from web.views import TestView
     9     urlpatterns = [
    10         url(r'^test/', TestView.as_view(),name='test'),
    11     ]
    12     
    13     #!/usr/bin/env python
    14     # -*- coding:utf-8 -*-
    15     from rest_framework.views import APIView
    16     from rest_framework.response import Response
    17     from rest_framework.versioning import QueryParameterVersioning
    18     class TestView(APIView):
    19         versioning_class = QueryParameterVersioning
    20         def get(self, request, *args, **kwargs):
    21             # 获取版本
    22             print(request.version)
    23             # 获取版本管理的类
    24             print(request.versioning_scheme)
    25             # 反向生成URL
    26             reverse_url = request.versioning_scheme.reverse('test', request=request)
    27             print(reverse_url)
    28             return Response('GET请求,响应内容')
    29         def post(self, request, *args, **kwargs):
    30             return Response('POST请求,响应内容')
    31         def put(self, request, *args, **kwargs):
    32             return Response('PUT请求,响应内容')
    View Code

    基于url正则方式

     1 urls
     2     from django.conf.urls import url, include
     3     from web.views import TestView
     4 
     5     urlpatterns = [
     6         url(r'^(?P<version>[v1|v2]+)/test/', TestView.as_view(), name='test'),
     7     ]
     8 
     9     views
    10     
    11     from rest_framework.views import APIView
    12     from rest_framework.response import Response
    13     from rest_framework.versioning import URLPathVersioning
    14     class TestView(APIView):
    15         versioning_class = URLPathVersioning
    16 
    17         def get(self, request, *args, **kwargs):
    18             # 获取版本
    19             print(request.version)
    20             # 获取版本管理的类
    21             print(request.versioning_scheme)
    22 
    23             # 反向生成URL
    24             reverse_url = request.versioning_scheme.reverse('test', request=request)
    25             print(reverse_url)
    26 
    27             return Response('GET请求,响应内容')
    28 
    29         def post(self, request, *args, **kwargs):
    30             return Response('POST请求,响应内容')
    31 
    32         def put(self, request, *args, **kwargs):
    33             return Response('PUT请求,响应内容')
    34 
    35     setting
    36     REST_FRAMEWORK = {
    37         'DEFAULT_VERSION': 'v1',            # 默认版本
    38         'ALLOWED_VERSIONS': ['v1', 'v2'],   # 允许的版本
    39         'VERSION_PARAM': 'version'          # URL中获取值的key
    40     }
    View Code

    基于 accept 请求头方式

     1 REST_FRAMEWORK = {
     2         'DEFAULT_VERSION': 'v1',            # 默认版本
     3         'ALLOWED_VERSIONS': ['v1', 'v2'],   # 允许的版本
     4         'VERSION_PARAM': 'version'          # URL中获取值的key
     5     }
     6     
     7     from django.conf.urls import url, include
     8     from web.views import TestView
     9 
    10     urlpatterns = [
    11         url(r'^test/', TestView.as_view(), name='test'),
    12     ]
    13 
    14     #!/usr/bin/env python
    15     # -*- coding:utf-8 -*-
    16     from rest_framework.views import APIView
    17     from rest_framework.response import Response
    18     from rest_framework.versioning import AcceptHeaderVersioning
    19 
    20 
    21     class TestView(APIView):
    22         versioning_class = AcceptHeaderVersioning
    23 
    24         def get(self, request, *args, **kwargs):
    25             # 获取版本 HTTP_ACCEPT头
    26             print(request.version)
    27             # 获取版本管理的类
    28             print(request.versioning_scheme)
    29             # 反向生成URL
    30             reverse_url = request.versioning_scheme.reverse('test', request=request)
    31             print(reverse_url)
    32 
    33             return Response('GET请求,响应内容')
    34 
    35         def post(self, request, *args, **kwargs):
    36             return Response('POST请求,响应内容')
    37 
    38         def put(self, request, *args, **kwargs):
    39             return Response('PUT请求,响应内容') 
    View Code

    全局使用

     1 settings.py
     2     REST_FRAMEWORK = {
     3         'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning",
     4         'DEFAULT_VERSION': 'v1',
     5         'ALLOWED_VERSIONS': ['v1', 'v2'],
     6         'VERSION_PARAM': 'version' 
     7     }
     8     views
     9     from rest_framework.views import APIView
    10     from rest_framework.response import Response
    11     from rest_framework.versioning import URLPathVersioning
    12     class TestView(APIView):
    13         def get(self, request, *args, **kwargs):
    14             # 获取版本
    15             print(request.version)
    16             # 获取版本管理的类
    17             print(request.versioning_scheme)
    18 
    19             # 反向生成URL
    20             reverse_url = request.versioning_scheme.reverse('test', request=request)
    21             print(reverse_url)
    22 
    23             return Response('GET请求,响应内容')
    24 
    25         def post(self, request, *args, **kwargs):
    26             return Response('POST请求,响应内容')
    27 
    28         def put(self, request, *args, **kwargs):
    29             return Response('PUT请求,响应内容')
    View Code
  • 相关阅读:
    【并发编程】多线程并发最佳实践
    【并发编程】死锁
    【并发编程】【JDK源码】J.U.C--线程池
    【并发编程】【JDK源码】J.U.C--组件FutureTask、ForkJoin、BlockingQueue
    【JVM】关于类加载器准备阶段的一道面试题目
    【并发编程】【JDK源码】J.U.C--AQS 及其同步组件(2/2)
    【并发编程】线程安全策略
    JSP 9大内置对象详解
    Jquery中的bind(),live(),delegate(),on()绑定事件方式
    阻止事件冒泡
  • 原文地址:https://www.cnblogs.com/daidechong/p/10452096.html
Copyright © 2020-2023  润新知