zoukankan      html  css  js  c++  java
  • 深入解析当下大热的前后端分离组件django-rest_framework系列四

    查漏补缺系列

    解析器

    request类

    django的request类和rest-framework的request类的源码解析

    局部视图

    复制代码
    复制代码
    from rest_framework.parsers import JSONParser,FormParser
    class PublishViewSet(generics.ListCreateAPIView):
        parser_classes = [FormParser,JSONParser]
        queryset = Publish.objects.all()
        serializer_class = PublshSerializers
        def post(self, request, *args, **kwargs):
            print("request.data",request.data)
            return self.create(request, *args, **kwargs)
    复制代码
    复制代码

    全局视图

    复制代码
    复制代码
    REST_FRAMEWORK={
        "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",],
        "DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",],
        "DEFAULT_THROTTLE_CLASSES":["app01.service.throttles.VisitThrottle",],
        "DEFAULT_THROTTLE_RATES":{
            "visit_rate":"5/m",
        },
        "DEFAULT_PARSER_CLASSES":['rest_framework.parsers.FormParser',]
    }
    复制代码
    复制代码

    备注:局部使用指定解析器时,只需在视图类中添加一个变量:parser_classes = [...]

    rest_framework全局默认使用的解析器:

    复制代码
    DEFAULTS = {
        # Base API policies
    
        'DEFAULT_PARSER_CLASSES': (
            'rest_framework.parsers.JSONParser',
            'rest_framework.parsers.FormParser',
            'rest_framework.parsers.MultiPartParser'
        ),
    复制代码

    分页

    简单分页

    复制代码
    复制代码
    from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination
    
    class PNPagination(PageNumberPagination):
            page_size = 1     # 每页显示的数据个数
            page_query_param = 'page'    #翻页的参数  ?page=num
            page_size_query_param = "size"    #每页临时显示的数据个数  覆盖page_size
            max_page_size = 5     #每页允许显示的最大条数
    
    class BookViewSet(viewsets.ModelViewSet):
    
        queryset = Book.objects.all()
        serializer_class = BookSerializers
        def list(self,request,*args,**kwargs):
         # 单写某个视图时的用法
            book_list=Book.objects.all()
            pp=LimitOffsetPagination()
            pager_books=pp.paginate_queryset(queryset=book_list,request=request,view=self)
            print(pager_books)
            bs=BookSerializers(pager_books,many=True)
    
            #return Response(bs.data)
            return pp.get_paginated_response(bs.data)
    复制代码
    复制代码

    偏移分页

    from rest_framework.pagination import LimitOffsetPagination

    分页器在视图类中的用法:在视图类中定义一个变量: pagination_class=类

     备注:使用LimitOffsetPagination偏移分页,里面的两个参数limit和offset:limit是每页显示的条数,offset是从第几条数据+1开始(offset=3,意为从第四条数据开始)。default_limit = num,默认显示的条数。

    游标分页

    复制代码
    from rest_framework.views import APIView
    from .models import UserInfo
    from rest_framework.response import Response
    from rest_framework import serializers
    from rest_framework.pagination import CursorPagination
    class MyPagination(CursorPagination):
        # URL传入的游标参数
        cursor_query_param = 'cursor'
        # 默认每页显示的数据条数
        page_size = 2
        # URL传入的每页显示条数的参数
        page_size_query_param = 'page_size'
        # 每页显示数据最大条数
        max_page_size = 1000
    
        # 根据ID从大到小排列
        ordering = "id"
    class PagerSerialize(serializers.ModelSerializer):
        '''数据序列化'''
        class Meta:
            model = UserInfo
            fields = "__all__"
            depth = 2     #用于显示关联字段的对应的表的详细内容
    
    class PagerView(APIView):
        def get(self,request,*args,**kwargs):
            user_list=UserInfo.objects.all().order_by('-id')  #将数据按照id从大到小排序
            #根据url参数,获取分页数据
            obj=MyPagination()
            page_user_list=obj.paginate_queryset(user_list,request,self)
    
            #数据进行序列化
            ser=PagerSerialize(instance=page_user_list,many=True)
            response=obj.get_paginated_response(ser.data)  #返回带上下页连接的数据
            return response
            # return Response(ser.data)   #不含上下页链接
    复制代码

    游标方式分页的本质是通过记住当前页面数据的最大、最小id,翻页时根据记录的最大或者最小id,查询下一页对应的数据,这样就不会出现每一次翻页都会重头遍历数据的情况,大大的提高了查询效率。缺点是无法直接跳转到某一页。

    url路由器

    我们在使用rest_framework时,url都是一个规定的格式,当我们有很多表时,意味着大量的复用一些代码,对于每一个模型表对应的url,只有两个地方不同,一个是路径的前缀,一个是对应的视图类。在rest_framework中也提供了一个url的分发,完美的解决了url的分发。

    from rest_framework import routers

    rest_framework提供一个routers的py文件,这个文件中包含跟路由相关的类。

    使用方式:在routers.py中有一个DefaultRouter类,先实例化一个这个类的对象,router=routers.DefaultRouter(),通过这个router对象,可以将对应的路径和视图类注册:router.register(r"路径前缀",对应的视图类),最后只需将url(r'^', include(router.urls)),这个url加入到urlpatterns中即可。

    备注:rest_framework中为我们提供了四种形式的访问方式:

    1. books/
    2. books/1/
    3. books.json/
    4. books/?format=json            后两种不常用

    响应器

    rest_framework默认提供给我们两种响应器:

    复制代码
    DEFAULTS = {
        # Base API policies
        'DEFAULT_RENDERER_CLASSES': (
            'rest_framework.renderers.JSONRenderer',
            'rest_framework.renderers.BrowsableAPIRenderer',
        ),
    复制代码

    如果请求是浏览器,就用BrowsableAPIRenderer响应器返回一个页面,如果请求是非浏览器(比如Postman),就使用JSONRenderer响应一个json格式的数据。rest_framework提供这两个响应器是为了利于开发。

      我们可以在视图类中配置一个变量:renderer_classes = [JSONRenderer]

    from rest_framework.renderers import JSONRenderer

    这样我们再使用浏览器发送请求是,响应的是一个json格式的字符串,而不是一个界面。

    版本控制

      版本控制是由传入的客户端请求决定的,并且可能基于请求URL,或者基于请求头。

      restframework也提供了对应的版本控制。当使用版本控制时,request.version属性(字符串)与客户端请求的版本一致。 默认情况下,没有使用版本控制,request.version将会返回None,我们可以通过request.version的值进行判断和逻辑分发.

    基于请求url:

    复制代码
    class APIView(View):
        # 版本控制的默认配置    可以在局部中定义versoning_class=的自定义配置
        versioning_class = api_settings.DEFAULT_VERSIONING_CLASS
    
    
         def initial(self, request, *args, **kwargs):
            #  版本控制相关
            # Determine the API version, if versioning is in use.
            version, scheme = self.determine_version(request, *args, **kwargs)
            request.version, request.versioning_scheme = version, scheme   
    复制代码

    版本配置

    全局配置

    1. 添加配置
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    REST_FRAMEWORK = {
                  
                 ....
                  
                 'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning',
                 'ALLOWED_VERSIONS':['v1','v2'], # 允许的版本
                 'VERSION_PARAM':'version', # 参数
                 'DEFAULT_VERSION':'v1', # 默认版本
                 ....
          }
    2. 设置路由 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    BeesCity/urls.py
                 urlpatterns = [
                        #url(r'^admin/', admin.site.urls),
                        url(r'^api/(?P<version>w+)/', include('api.urls')),
                 ]
           
          api/urls.py
                 urlpatterns = [
                        url(r'^course/$', course.CourseView.as_view()),
                 ]
    3. 传递版本信息
    1
    http://127.0.0.1:8000/api/v1/course/
    4. 获取版本 
    1
    request.version 获取版本 

    局部配置

    除非明确设置,否则DEFAULT_VERSIONING_CLASS值为None.此例中request.version将会始终返回None 
    您还可以在一个单独的视图上设置版本控制方案。通常,您不需要这样做,因为在全局范围内使用一个版本控制方案更有意义。如果您确实需要这样做,请使用versioning_class属性。

    1
    2
    3
    4
    from rest_framework.versioning import QueryParameterVersioning
     
    class Course(APIView):
        versioning_class = QueryParameterVersioning

      这个时候可以用过url传参的方式来传递版本信息,如:

    1
    http://127.0.0.1:8000/api/course/?version=1

    添加头信息控制版本

    在API请求header中添加Accept字段。
    Accept的作用是客户端指出响应可以接受的媒体类型
    如Accept:application/json; version=v2
    具体格式也可以参考下面。

    Accept: application/vnd.xxxx[.version].param[+json]

    例如Accept: application/vnd.demo.app-v2+json

      总结:小版本的更新可通过把版本号作为参数的方式或者通过accept字段标示版本号的方式判断,大的版本更新则通过URL上添加版本号控制

  • 相关阅读:
    一维数组遍历
    实战级Stand-Alone Self-Attention in CV,快加入到你的trick包吧 | NeurIPS 2019
    ThunderNet :像闪电一样,旷视再出超轻量级检测器,高达267fps | ICCV 2019
    Light-Head R-CNN : 旷世提出用于加速two-stage detector的通用结构,速度达102fps
    NASNet : Google Brain经典作,改造搜索空间,性能全面超越人工网络,继续领跑NAS领域 | CVPR 2018
    ICLR 2020 | 抛开卷积,multi-head self-attention能够表达任何卷积操作
    告别炼丹,Google Brain提出强化学习助力Neural Architecture Search | ICLR2017
    AAAI 2020 | 反向R?削弱显著特征为细粒度分类带来提升
    AAAI 2020 | DIoU和CIoU:IoU在目标检测中的正确打开方式
    目标检测 | 经典算法 Cascade R-CNN: Delving into High Quality Object Detection
  • 原文地址:https://www.cnblogs.com/zhaopanpan/p/9464995.html
Copyright © 2011-2022 走看看