zoukankan      html  css  js  c++  java
  • rest-framework(2)

      一.分页

      ps:当数据量比较大时,如何解决分页问题?

       解决思路(3种):

       1.记录当前访问页的数据id;(比如访问下一页时,记录当前页的最后一条数据id)

       2.最多显示固定页数(比如只显示100页或120页,超过了则不显示)

       3.只显示上一页和下一页,并对页码进行加密

      分页的实现

        1.基于limitoffset

       导入

    from rest_framework.pagination import LimitOffsetPagination

         示例代码

    1 urlpatterns = [
    2      url(r'^admin/', admin.site.urls),
    3      url(r'^app01/(?P<version>[v1|v2]+)/', include('app01.urls'))
    4  ]
    urls.py
    1 urlpatterns = [
    2     url(r'^index1/', views.IndexView1.as_view()),
    3     url(r'^index2/', views.IndexView2.as_view()),
    4     url(r'^index3/', views.IndexView3.as_view()),
    5     url(r'^index4/', views.IndexView4.as_view()),
    6     url(r'^index5/', views.IndexView5.as_view()),
    7 ]
    app01.urls
     1 from rest_framework.views import APIView
     2 from rest_framework.response import Response
     3 from app01.serializes.myserializes import MySerializes
     4 from rest_framework.pagination import LimitOffsetPagination
     5 from app01 import models
     6 
     7 # =========== 可以自己进行自定制分页,基于limitoffset===================
     8 class P1(LimitOffsetPagination):
     9     max_limit = 3  # 最大限制默认是None
    10     default_limit =2  # 设置每一页显示多少条
    11     limit_query_param = 'limit'  # 往后取几条
    12     offset_query_param = 'offset'  # 当前所在的位置
    13 
    14 class IndexView2(APIView):
    15     #使用http://127.0.0.1:8080/app01/v1/index2/?offset=2&limit=4可进行判断
    16     def get(self,request,*args,**kwargs):
    17         user_list = models.UserInfo.objects.all()
    18         p1 = P1()#注册分页
    19         page_user_list = p1.paginate_queryset(queryset=user_list,request=request,view=self)
    20         print('打印的是分页的数据',page_user_list)
    21         ser = MySerializes(instance=page_user_list,many=True)  #可允许多个
    22         # return Response(ser.data) #不含上一页下一页
    23         return p1.get_paginated_response(ser.data)
    24 
    25 =======================也可用下面这种形式===========
    26 class BaseResponse(object):
    27     def __init__(self,code=1000,data=None,error=None):
    28         self.code = code
    29         self.data = data
    30         self.error = error
    31 class IndexView(views.APIView):
    32     '''类表示的方式'''
    33     def get(self,request,*args,**kwargs):
    34         ret = BaseResponse()
    35         try:
    36             user_list = models.UserInfo.objects.all()
    37             p1 = P1()
    38             page_user_list = p1.paginate_queryset(queryset=user_list,request=request,view=self)
    39             ser = IndexSerializer(instance=page_user_list,many=True)
    40             ret.data = ser.data
    41             ret.next = p1.get_next_link()
    42         except Exception as e:
    43             ret.code= 1001
    44             ret.error = 'xxxx错误'
    45         return Response(ret.__dict__)
    views.py

       2.基于页码的分页

           导入

    from rest_framework.pagination import PageNumberPagination
     1 # ======================基于页码实现的分页==============
     2 class P2(PageNumberPagination):
     3     #默认每页显示的数据条数
     4     page_size = 2
     5     #获取url参数中设置的每页显示数据条数
     6     page_size_query_param = 'size'
     7     #获取url中传入的页码key
     8     page_query_param = 'page'
     9     #最大支持的每页显示的数据条数
    10     max_page_size = 5
    11 
    12 class IndexView3(APIView):
    13     #使用http://127.0.0.1:8080/app01/v1/index3/?page=1&page_size=1可进行判断
    14     def get(self,request,*args,**kwargs):
    15         user_list = models.UserInfo.objects.all()
    16         #实例化分页对象,获取数据库中的分页数据
    17         p2 = P2()
    18         print(p2.page_size_query_description)
    19         page_user_list = p2.paginate_queryset(queryset=user_list,request=request,view=self)
    20         print('打印的是分页的数据',page_user_list)
    21 
    22         #序列化对象
    23         ser = MySerializes(instance=page_user_list,many=True)  #可允许多个
    24 
    25         #生成分页和数据
    26         # return Response(ser.data) #不含上一页下一页
    27         return p2.get_paginated_response(ser.data)
    28 
    29 views.py
    views.py

        3.基于Cursor的分页(页码加密)

     1 # =====================基于Cursor的分页============
     2 class P3(CursorPagination):
     3     # URL传入的游标参数
     4     cursor_query_param = 'cursor'
     5     # 默认每页显示的数据条数
     6     page_size = 2
     7     # URL传入的每页显示条数的参数
     8     page_size_query_param = 'size'
     9     # 每页显示数据最大条数
    10     max_page_size = 3
    11 
    12     # 根据ID从大到小排列
    13     ordering = "id"
    14     
    15 class IndexView4(APIView):
    16     #使用http://127.0.0.1:8080/app01/v1/index4/?cursor=cj0xJnA9NA%3D%3D&size=3可进行判断
    17     def get(self,request,*args,**kwargs):
    18         user_list = models.UserInfo.objects.all().order_by('-id')
    19         p3 = P3()#注册分页
    20         page_user_list = p3.paginate_queryset(queryset=user_list,request=request,view=self)
    21         print('打印的是分页的数据',page_user_list)
    22         ser = MySerializes(instance=page_user_list,many=True)  #可允许多个
    23         # return Response(ser.data) #不含上一页下一页
    24         return p3.get_paginated_response(ser.data)
    views.py

      二.视图

      写视图函数时,用的最多的就是APIview,当然其他的也有必要了解下

       先导入

    from rest_framework.views import APIView
    from rest_framework.generics import GenericAPIView
    from rest_framework.viewsets import GenericViewSet
    from rest_framework.viewsets import ModelViewSet

      1.APIview

    1 class IndexView2(APIView):
    2      def get(self,request,*args,**kwargs):
    3          user_list = models.UserInfo.objects.all()
    4          ser = MySerializes(instance=user_list,many=True)
    5          return Response(ser.data)
    View Code

      2.GenericAPIview(APIView)

     1 from rest_framework.response import Response
     2 from rest_framework.generics import GenericAPIView
     3 from app01 import models
     4 from app01.serializes.myserializes import MySerializes
     5 from rest_framework.pagination import LimitOffsetPagination
     6 class P1(LimitOffsetPagination):
     7     max_limit = 3  # 最大限制默认是None
     8     default_limit =2  # 设置每一页显示多少条
     9     limit_query_param = 'limit'  # 往后取几条
    10     offset_query_param = 'offset'  # 当前所在的位置
    11 
    12 class IndexView1(GenericAPIView):
    13     queryset = models.UserInfo.objects.all()
    14     serializer_class = MySerializes
    15     pagination_class = P1
    16     def get(self,request,*args,**kwargs):
    17         user_list = self.get_queryset()
    18         p1 = P1()  #注册分页
    19         data = p1.paginate_queryset(queryset=user_list,request=request,view=self)  #获取分页的数据
    20         ser = self.get_serializer(instance=data,many=True) #序列化
    21         return Response(ser.data)
    22 
    23 GenericAPIView
    View Code

      3.GenericViewSet(ViewSetMixin, generics.GenericAPIView)

     1  2     POST
     3     /users/
     4  5     DELETE
     6     /users/1/
     7#全部修改
     8     PUT
     9     /users/1/
    10     #局部修改
    11     patch
    12     /users/1/
    13 14     GET
    15     /users/ 
    16     GET
    17     /users/1/
    18 在GET请求的时候如果带ID说明查一条,如果不带则查所有
    View Code

      示例:

    1 urlpatterns = [ 
    2      url(r'^index/$', views.IndexView.as_view()),
    3      url(r'^index/(?P<pk>d+)$', views.IndexView.as_view()),
    4  ]
    urls.py
     1 class IndexView(views.APIView):
     2 
     3     def get(self,request,*args,**kwargs):
     4         pk = kwargs.get('pk')
     5         if pk:
     6             pass # 获取单条信息
     7         else:
     8             pass # 获取列表信息
     9 
    10     def post(self,request,*args,**kwargs):
    11         pass
    12 
    13     def put(self,request,*args,**kwargs):
    14         pass
    15 
    16     def patch(self,request,*args,**kwargs):
    17         pass
    18 
    19     def delete(self,request,*args,**kwargs):
    20                 pass
    views.py

      用GenericViewSet:

    1 urlpatterns = [
    2      url(r'^index3/$', views.IndexView3.as_view({'get': 'list','post':'create'})),
    3      url(r'^index3/(?P<pk>d+)/$', views.IndexView3.as_view({'get': 'retrieve'})),
    4      ]
    urls.py
     1 class IndexView3(GenericViewSet):
     2     queryset = models.UserInfo.objects.all()
     3     serializer_class = MySerializes
     4     pagination_class = P1
     5 
     6     def list(self,request,*args,**kwargs):
     7         #获取列表信息
     8         return Response('...')
     9 
    10     def retrieve(self,request,*args,**kwargs):
    11         #获取单条数据
    12         return Response('xxx')
    views.py 

      4. ModelViewSet(mixins.CreateModelMixin,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin,

    mixins.ListModelMixin,GenericViewSet)

           利用ModelViewSet增删改查不用自己写了,内部把增删改查都干了,当满足不了需求的时候我们也可以自定制

     1 urlpatterns = [
     2 
     3     url(r'^index4/', views.IndexView4.as_view({'get': 'list','post':'create'})),  #获取数据和添加数据
     4     url(r'^index4.(?P<format>[a-z0-9]+)/', views.IndexView4.as_view({'get': 'list','post':'create'})), #.json想让页面上显示成json格式
     5     url(r'^index4/(?P<pk>d+)/', views.IndexView4.as_view({'get': 'retrieve', 'delete': 'destroy','put':'partial_update'})), #查看单条,删除,修改数据
     6     url(r'^index4(?P<pk>d+).(?P<format>[a-z0-9]+)/', views.IndexView4.as_view({'get': 'retrieve', 'delete': 'destroy','put':'partial_update'})),
     7 
     8 ]
     9 
    10 urls.py
    urls.py
     1 注意啦:用ModelSerializer这种方法必须要用IndexSerializer(ModelSerializer)这种方式序列化
     2 class P2(PageNumberPagination):
     3     page_size = 3  #每一页显示的条数
     4     page_query_param = 'page' #获取参数中传入的页码
     5     page_size_query_param = 'size' #获取url参数中每页显示的数据条数
     6 
     7     max_page_size = 5
     8 
     9 class IndexSerializer(ModelSerializer):
    10     class Meta:
    11         model = models.UserInfo
    12         fields = "__all__"
    13 
    14 class IndexView4(ModelViewSet):
    15     queryset = models.UserInfo.objects.all()
    16     serializer_class = IndexSerializer
    17     pagination_class = P2
    Views.py

      自定制

     1 class P2(PageNumberPagination):
     2     page_size = 3  #每一页显示的条数
     3     page_query_param = 'page' #获取参数中传入的页码
     4     page_size_query_param = 'size' #获取url参数中每页显示的数据条数
     5 
     6     max_page_size = 5
     7 
     8 class IndexSerializer(ModelSerializer):
     9     class Meta:
    10         model = models.UserInfo
    11         fields = "__all__"
    12 
    13 class IndexView4(ModelViewSet):
    14     queryset = models.UserInfo.objects.all()
    15     serializer_class = IndexSerializer
    16     pagination_class = P2
    17 
    18     def list(self, request, *args, **kwargs):
    19         '''获取get请求的所有'''
    20         pass
    21 
    22     def retrieve(self, request, *args, **kwargs):
    23         '''查看单条数据'''
    24         pass
    25     def destroy(self, request, *args, **kwargs):
    26         '''删除DELETE'''
    27         pass
    28     def create(self, request, *args, **kwargs):
    29         '''添加数据POST'''
    30         pass
    31     def update(self, request, *args, **kwargs):
    32         '''全部修改PUT'''
    33         pass
    34     def partial_update(self, request, *args, **kwargs):
    35         '''局部修改PATCH'''
    36         pass
    37 
    38 基于ModelViewSet自定制
    View Code

       三.路由

      1.自定义路由

     1 # http://127.0.0.1:8000/api/v1/auth/
     2 url(r'^auth/$', views.AuthView.as_view()),
     3 # http://127.0.0.1:8000/api/v1/auth.json # 想要让页面显示json格式
     4 url(r'^auth.(?P<format>[a-z0-9]+)$', views.AuthView.as_view()),
     5 # http://127.0.0.1:8000/api/v1/auth/1/
     6 url(r'^auth/(?P<pk>d+)/$', views.AuthView.as_view()),
     7 # http://127.0.0.1:8000/api/v1/auth/1.json
     8 url(r'^auth/(?P<pk>d+).(?P<format>[a-z0-9]+)$', views.AuthView.as_view()),
     9 class AuthView(views.APIView):
    10 
    11     def get(self,request,*args,**kwargs):
    12         return Response('...')
    View Code

       2.半自动路由

    1 url(r'^index/$', views.IndexView.as_view({'get':'list','post':'create'})),
    2 url(r'^index.(?P<format>[a-z0-9]+)$', views.IndexView.as_view({'get':'list','post':'create'})),
    3 url(r'^index/(?P<pk>d+)/$', views.IndexView.as_view({'get':'retrieve','delete':'destroy','put':'update','patch':'partial_update'})),
    4 url(r'^index(?P<pk>d+).(?P<format>[a-z0-9]+)$', views.IndexView.as_view({'get':'retrieve','delete':'destroy','put':'update','patch':'partial_update'})),
    5 
    6 class IndexView(viewsets.ModelViewSet):
    7     queryset = models.UserInfo.objects.all()
    8     serializer_class = IndexSerializer
    9     pagination_class = P2
    View Code

      3.全自动路由,会自动生成四个url

     1 router = DefaultRouter()
     2 router.register('index',views.IndexViewSet)
     3 urlpatterns = [
     4     url(r'^', include(router.urls)),
     5 ]
     6 
     7 class IndexViewSet(viewsets.ModelViewSet):
     8     queryset = models.UserInfo.objects.all()
     9     serializer_class = IndexSerializer
    10     pagination_class = P2
    11     
    12 class IndexSerializer(serializers.ModelSerializer):
    13     class Meta:
    14         model = models.UserInfo
    15         fields = "__all__"
    View Code

      四.渲染器

      根据 用户请求URL 或 用户可接受的类型,筛选出合适的 渲染组件。
      用户请求URL:

    • http://127.0.0.1:8000/test/?format=json
    • http://127.0.0.1:8000/test.json

      用户请求头:

      Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

      1.Json

      访问URL

      http://127.0.0.1:8000/test/?format=json

      http://127.0.0.1:8000/test.json

      http://127.0.0.1:8000/test/ 

    Urls.py
     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 from rest_framework.views import APIView
     4 from rest_framework.response import Response
     5 from rest_framework import serializers
     6 
     7 from rest_framework.renderers import JSONRenderer
     8 
     9 from .. import models
    10 
    11 
    12 class TestSerializer(serializers.ModelSerializer):
    13     class Meta:
    14         model = models.UserInfo
    15         fields = "__all__"
    16 
    17 
    18 class TestView(APIView):
    19     renderer_classes = [JSONRenderer, ]
    20 
    21     def get(self, request, *args, **kwargs):
    22         user_list = models.UserInfo.objects.all()
    23         ser = TestSerializer(instance=user_list, many=True)
    24         return Response(ser.data)
    Views.py

      2.表格

      访问URL:

      http://127.0.0.1:8000/test/?format=admin

      http://127.0.0.1:8000/test.admin

      http://127.0.0.1:8000/test/ 

     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 from rest_framework.views import APIView
     4 from rest_framework.response import Response
     5 from rest_framework import serializers
     6 
     7 from rest_framework.renderers import AdminRenderer
     8 
     9 from .. import models
    10 
    11 
    12 class TestSerializer(serializers.ModelSerializer):
    13     class Meta:
    14         model = models.UserInfo
    15         fields = "__all__"
    16 
    17 
    18 class TestView(APIView):
    19     renderer_classes = [AdminRenderer, ]
    20 
    21     def get(self, request, *args, **kwargs):
    22         user_list = models.UserInfo.objects.all()
    23         ser = TestSerializer(instance=user_list, many=True)
    24         return Response(ser.data)
    Views.py

      3.From表单

      访问URL:

      http://127.0.0.1:8000/test/?format=form

      http://127.0.0.1:8000/test.form

      http://127.0.0.1:8000/test/ 

     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 from rest_framework.views import APIView
     4 from rest_framework.response import Response
     5 from rest_framework import serializers
     6 
     7 from rest_framework.renderers import JSONRenderer
     8 from rest_framework.renderers import AdminRenderer
     9 from rest_framework.renderers import HTMLFormRenderer
    10 
    11 from .. import models
    12 
    13 class TestSerializer(serializers.ModelSerializer):
    14     class Meta:
    15         model = models.UserInfo
    16         fields = "__all__"
    17 
    18 
    19 class TestView(APIView):
    20     renderer_classes = [HTMLFormRenderer, ]
    21 
    22     def get(self, request, *args, **kwargs):
    23         user_list = models.UserInfo.objects.all().first()
    24         ser = TestSerializer(instance=user_list, many=False)
    25         return Response(ser.data)
    Views.py

      4.自定义模版

      访问URL:

      http://127.0.0.1:8000/test/?format=html

      http://127.0.0.1:8000/test.html

      http://127.0.0.1:8000/test/ 

    1 from django.conf.urls import url, include
    2 from web.views import s11_render
    3 
    4 urlpatterns = [
    5     url(r'^test/$', s11_render.TestView.as_view()),
    6     url(r'^test.(?P<format>[a-z0-9]+)', s11_render.TestView.as_view()),
    7 ]
    urls.py
     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 from rest_framework.views import APIView
     4 from rest_framework.response import Response
     5 from rest_framework import serializers
     6 from rest_framework.renderers import TemplateHTMLRenderer
     7 
     8 from .. import models
     9 
    10 class TestSerializer(serializers.ModelSerializer):
    11     class Meta:
    12         model = models.UserInfo
    13         fields = "__all__"
    14 
    15 class TestView(APIView):
    16     renderer_classes = [TemplateHTMLRenderer, ]
    17 
    18     def get(self, request, *args, **kwargs):
    19         user_list = models.UserInfo.objects.all().first()
    20         ser = TestSerializer(instance=user_list, many=False)
    21         return Response(ser.data, template_name='user_detail.html')
    Views.py
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>Title</title>
     6 </head>
     7 <body>
     8     {{ user }}
     9     {{ pwd }}
    10     {{ ut }}
    11 </body>
    12 </html>
    Userdetail.html

      5.浏览器模式API+Json

      访问URL:

    http://127.0.0.1:8000/test/?format=api

      http://127.0.0.1:8000/test.api

      http://127.0.0.1:8000/test/ 

     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 from rest_framework.views import APIView
     4 from rest_framework.response import Response
     5 from rest_framework import serializers
     6 
     7 from rest_framework.renderers import JSONRenderer
     8 from rest_framework.renderers import BrowsableAPIRenderer
     9 
    10 from .. import models
    11 
    12 class TestSerializer(serializers.ModelSerializer):
    13     class Meta:
    14         model = models.UserInfo
    15         fields = "__all__"
    16 
    17 
    18 class CustomBrowsableAPIRenderer(BrowsableAPIRenderer):
    19     def get_default_renderer(self, view):
    20         return JSONRenderer()
    21 
    22 
    23 class TestView(APIView):
    24     renderer_classes = [CustomBrowsableAPIRenderer, ]
    25 
    26     def get(self, request, *args, **kwargs):
    27         user_list = models.UserInfo.objects.all().first()
    28         ser = TestSerializer(instance=user_list, many=False)
    29         return Response(ser.data, template_name='user_detail.html')
    View Code

      注意:如果同时多个存在时,自动根据URL后缀来选择渲染器。

  • 相关阅读:
    [django]media_url
    django部署到apache出现DLL load failed

    Django model relationship field
    python下划线变量的含义
    JavaScript 对象属性作实参以及实参对象的callee属性
    Javascript变长参数和默认参数
    JavaScript 数组
    JavaScript 操作对象属性(设置属性, setter/getter, 序列化)
    JavaScript 对象笔记
  • 原文地址:https://www.cnblogs.com/sxh-myblogs/p/8443252.html
Copyright © 2011-2022 走看看