zoukankan      html  css  js  c++  java
  • rest-framework

    1. 分页

    当数据量过大,如何修改查询规则:

      显示当前页的时候记录当前的最大id(和最小id,上一页的时候用的),假设为n,下一页的时候查询条件是id>n,这样,前n条就不用扫描了。(这里只显示上一页和下一页,没有具体页码)

      但是有一个缺点就是当用户修改url直接改成较大的数的时候还是会出现相同的情况。这是时我们把页码进行加密,这样用户就不能通过修改url来获取我们的数据了。

    分页有三个类
    1. PageNumberPagination
    class StandardResultsSetPagination(PageNumberPagination):  # 继承PageNumberPagination,就可以指定这些参数,不然需要在settings中加入配置
        # 默认每页显示的数据条数
        page_size = 1
        # 获取URL参数中设置的每页显示数据条数
        page_size_query_param = 'page_size'
    
        # 获取URL参数中传入的页码key
        page_query_param = 'page'
    
        # 最大支持的每页显示的数据条数
        max_page_size = 1
    
    
    class UserSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.UserInfo
            fields = "__all__"
    
    
    class UserViewSet(APIView):
        def get(self, request, *args, **kwargs):
            user_list = models.UserInfo.objects.all().order_by('-id')
    
            # 实例化分页对象,获取数据库中的分页数据
            paginator = StandardResultsSetPagination()
            page_user_list = paginator.paginate_queryset(queryset=user_list, request=self.request, view=self)
    
            # 序列化对象
            serializer = UserSerializer(page_user_list, many=True)
    
            # 生成分页和数据
            response = paginator.get_paginated_response(serializer.data)  # 这种方式是作为返回对象,响应体中会有上一页下一页的url
            return response

    2. LimitOffsetPagination(使用方法同一,配置参数不同)

    from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination
    
    
    class StandardResultsSetPagination(LimitOffsetPagination):
        # 默认每页显示的数据条数
        default_limit = 10
        # URL中传入的显示数据条数的参数
        limit_query_param = 'limit'  # 搜寻多少个数据
        # URL中传入的数据位置的参数
        offset_query_param = 'offset'  # 从哪一条记录开始往后搜
        # 最大每页显得条数
        max_limit = None
    
    class UserSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.UserInfo
            fields = "__all__"
    
    
    class UserViewSet(APIView):
        def get(self, request, *args, **kwargs):
            user_list = models.UserInfo.objects.all().order_by('-id')
    
            # 实例化分页对象,获取数据库中的分页数据
            paginator = StandardResultsSetPagination()
            page_user_list = paginator.paginate_queryset(user_list, self.request, view=self)
    
            # 序列化对象
            serializer = UserSerializer(page_user_list, many=True)
    
            # 生成分页和数据
            response = paginator.get_paginated_response(serializer.data)
            return response

    3. CursorPagination(使用方法同一,配置参数不同)(只显示上一页,下一页,没有其他页码)

    from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
    
    
    class StandardResultsSetPagination(CursorPagination):
        # URL传入的游标参数
        cursor_query_param = 'cursor'
        # 默认每页显示的数据条数
        page_size = 2
        # URL传入的每页显示条数的参数
        page_size_query_param = 'page_size'
        # 每页显示数据最大条数
        max_page_size = 1000
    
        # 根据ID从大到小排列
        ordering = "id"
    
    
    
    class UserSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.UserInfo
            fields = "__all__"
    
    
    class UserViewSet(APIView):
        def get(self, request, *args, **kwargs):
            user_list = models.UserInfo.objects.all().order_by('-id')
    
            # 实例化分页对象,获取数据库中的分页数据
            paginator = StandardResultsSetPagination()
            page_user_list = paginator.paginate_queryset(user_list, self.request, view=self)
    
            # 序列化对象
            serializer = UserSerializer(page_user_list, many=True)
    
            # 生成分页和数据
            response = paginator.get_paginated_response(serializer.data)
            return response

    2. 路由与渲染器

    1. 路由
    如果前端需要获得json数据,可以通过访问url
       /api/v1/user/?format=json(普通方式)
    或者/api/v1/user.json(rest-framework提供的额外方式)
    实现方法:
      记不太清了。里面有个router。然后注册视图:router.register(
    'user', views.UserInfoView) # view.UserInfoView是需要做路由的视图,user会在url中使用,/api/v1/user


    2. 渲染器(即返会的数据将会以什么样的格式显示)

    class TestView(APIView):
        renderer_classes = [JSONRenderer, BrowsableAPIRenderer]  # 视图中这样配置即可,它会自动识别
    
        def get(self, request, *args, **kwargs):
            user_list = models.UserInfo.objects.all()
            ser = TestSerializer(instance=user_list, many=True)
            return Response(ser.data)
    
    

    3. 视图

    GenericAPIView继承了APIView,里面封装了queryset,pagination,serializer等方法 ------- 单纯的用这个方法没有意义

    GenericViewSet继承了ViewSetMixin和GenericAPIView,此时路由里面多了一个对应关系.as_view({'get': 'list'})。当请求方式为get时,执行该类的list方法,没有就去父类里面找

    ModelViewSet继承了mixins.ListModelMixin, mixins.CreateModelMixin, ...,GenericViewSet等六个类  ----  功能最全

    仅举例ModelViewSet的使用

    url.py
    urlpatterns = [
    
        url(r'^(?P<version>[v1|v2]+)/v1/$', views.View1View.as_view({'get': 'list', 'post': 'create'})),
        # 需要指定id的情况,这里的retrieve是用来获取单条数据
        url(r'^(?P<version>[v1|v2]+)/v1/(?P<pk>d+)/$', views.View1View.as_view({'get': 'retrieve', 'delete': 'destroy'})),
    ]

     views.py

    from rest_framework.viewsets import ModelViewSet
    
    
    class View1View(ModelViewSet):
        queryset = models.Role.objects.all()
        serializer_class = PagerSerialiser
        pagination_class = PageNumberPagination
  • 相关阅读:
    无法重用Linq2Entity Query
    The Joel Test
    MSBuilder directly instead of default VSComplie with keyborad shotcut 原创
    客户端缓存(Client Cache)
    关于代码重构和UT的一些想法,求砖头
    ExtJS2.0实用简明教程 应用ExtJS
    Perl information,doc,module document and FAQ.
    使用 ConTest 进行多线程单元测试 为什么并行测试很困难以及如何使用 ConTest 辅助测试
    史上最简单的Hibernate入门简介
    汽车常识全面介绍 传动系统
  • 原文地址:https://www.cnblogs.com/JackShi/p/13333756.html
Copyright © 2011-2022 走看看