rest-framework(2)

  一.分頁html

  ps:當數據量比較大時,如何解決分頁問題?
python

   解決思路(3種):web

   1.記錄當前訪問頁的數據id;(好比訪問下一頁時,記錄當前頁的最後一條數據id)數據庫

   2.最多顯示固定頁數(好比只顯示100頁或120頁,超過了則不顯示)django

   3.只顯示上一頁和下一頁,並對頁碼進行加密json

  分頁的實現api

    1.基於limitoffset瀏覽器

   導入app

from rest_framework.pagination import LimitOffsetPagination

     示例代碼ide

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後綴來選擇渲染器。

本站公眾號
   歡迎關注本站公眾號,獲取更多信息