首页 > 技术文章 > drf分页功能

YZL2333 2019-11-06 15:28 原文

 

  1. 什么是restful规范

    是一套规则,用于程序之间进行数据交换的约定。
    他规定了一些协议,对我们感受最直接的的是,以前写增删改查需要写4个接口,restful规范的就是1
    个接口,根据method的不同做不同的操作,比如:get/post/delete/put/patch/delete.
    初次之外,resetful规范还规定了:
    - 数据传输通过json
    扩展:前后端分离、app开发、程序之间(与编程语言无关)
    JSON:
     {
       name:'alex',
       age:18,
       gender:''
     }
    以前用webservice,数据传输格式xml。
    XML
    <name>alex</name>
    <age>alex</age>
    <gender>男</gender>

     

  2. 什么是drf?

    drf是一个基于django开发的组件,本质是一个django的app。
    drf可以办我们快速开发出一个遵循restful规范的程序。

     

  3. drf如何帮助我们快速开发的?drf提供了那些功能?

    - 视图,APIView用处还不知道。
    - 解析器,根据用户请求体格式不同进行数据解析,解析之后放在request.data中。
        在进行解析时候,drf会读取http请求头 content-type.
        如果content-type:x-www-urlencoded,那么drf会根据 & 符号分割的形式去处理请求体。
        user=wang&age=19
        
        如果content-type:application/json,那么drf会根据 json 形式去处理请求体。
        {"user":"wang","age":19}
    - 序列化,可以对QuerySet进行序列化,也可以对用户提交的数据进行校验。
    - 渲染器,可以帮我们把json数据渲染到页面上进行友好的展示。(内部会根据请求设备不同做不同的
    展示)

     

  4. 序列化:many=True or False

  5. 序列化:展示特殊的数据(choices、FK、M2M)可使用

    depth
    source,无需加括号,在源码内部会去判断是否可执行,如果可执行自动加括号。[fk/choice]
    SerializerMethodField,定义钩子方法。[m2m]

     

  6. 写程序的潜规则:约束

    # 约束子类中必须实现f1
    class Base(object):
    def f1(self):
    raise NotImplementedError('asdfasdfasdfasdf')
    class Foo(Base):
    def f1(self):
    print(123)
    obj = Foo()
    obj.f1()

     

  7. 面向对象的继承

    class Base(object):
        def f1(self):
            print('base.f1')
            self.f2()
        def f2(self):
            print('base.f2')
            
    class Foo(Base):
        def f2(self):
            print('foo.f2')
            
    obj = Foo()
    obj.f1()
    class Base(object):
        x1 = 123
        def f1(self):
            print(self.x1)
    class Foo(Base):
        x1 = 456
        
    obj = Foo()
    obj.f1()
    class APIView(object):
        version_class = 123
       
        def get_version(self):
            print(self.version_class)
    
    class UserView(APIView):
        version_class = 666
        
    obj = UserView()
    obj.get_version()
    class APIView(object):
        version_class = 123
        def dispatch(self,method):
            self.initial()
            getattr(self,method)()
        def initial(self):
            print(self.version_class)
       
    class UserView(APIView):
        version_class = 666
        def get(self):
            print('userview.get')
    
    obj = UserView()
    obj.dispatch('get')
    class URLPathVersion(object):
        
       def determin_version(self):
           return 'v1'
     
    class APIView(object):
        version_class = None
        def dispatch(self,method):
                version = self.initial()
             print(version)
                getattr(self,method)()
            
         def initial(self):
             self.process_version()
    
         def process_version():
             obj = self.version_class()
             return obj.determine_version()
       
    class UserView(APIView):
        version_class = URLPathVersion
    View Code

     

     

分页

  1. 分页

    1.1 PageNumberPagination

    • 配置 settings.py

      REST_FRAMEWORK = {
       "PAGE_SIZE":2
      }

       

    • 在视图的列表页面

      from rest_framework.pagination import PageNumberPagination
      from rest_framework import serializers
      
      class PageArticleSerializer(serializers.ModelSerializer):
          class Meta:
             model = models.Article
             fields = "__all__"
          
      class PageArticleView(APIView):
          
           def get(self,request,*args,**kwargs):
             queryset = models.Article.objects.all()
             # 方式一:仅数据
             """
             # 分页对象
             page_object = PageNumberPagination()
             # 调用 分页对象.paginate_queryset方法进行分页,得到的结果是分页之后的数据
             # result就是分完页的一部分数据
             result = page_object.paginate_queryset(queryset,request,self)
             # 序列化分页之后的数据
             ser = PageArticleSerializer(instance=result,many=True)
             return Response(ser.data)
             """
             # 方式二:数据 + 分页信息
             """
             page_object = PageNumberPagination()
             result = page_object.paginate_queryset(queryset, request, self)
             ser = PageArticleSerializer(instance=result, many=True)
             return page_object.get_paginated_response(ser.data)
             """
             # 方式三:数据 + 部分分页信息
             page_object = PageNumberPagination()
             result = page_object.paginate_queryset(queryset, request, self)
             ser = PageArticleSerializer(instance=result, many=True)
             return Response({'count':page_object.page.paginator.count,'result':ser.data})
      View Code

       

    • LimitOffsetPagination

      from rest_framework.pagination import PageNumberPagination
      from rest_framework.pagination import LimitOffsetPagination
      from rest_framework import serializers
      
      class PageArticleSerializer(serializers.ModelSerializer):
           class Meta:
             model = models.Article
             fields = "__all__"
      class HulaLimitOffsetPagination(LimitOffsetPagination):
           max_limit = 2
       
      class PageArticleView(APIView):
           def get(self,request,*args,**kwargs):
                 queryset = models.Article.objects.all()
                 page_object = HulaLimitOffsetPagination()
                 result = page_object.paginate_queryset(queryset, request, self)
                 ser = PageArticleSerializer(instance=result, many=True)
                 return Response(ser.data)

       

    • 扩展

      url(r'^page/view/article/$', views.PageViewArticleView.as_view()),
      from rest_framework.generics import ListAPIView
      class PageViewArticleSerializer(serializers.ModelSerializer):
           class Meta:
             model = models.Article
             fields = "__all__"
      class PageViewArticleView(ListAPIView):
           queryset = models.Article.objects.all()
           serializer_class = PageViewArticleSerializer
      REST_FRAMEWORK = {
       "PAGE_SIZE":2,
       "DEFAULT_PAGINATION_CLASS":"rest_framework.pagination.PageNumberPagination"
      }

       

       

 

 

 

 

 

推荐阅读