博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django Rest Framework 4
阅读量:4971 次
发布时间:2019-06-12

本文共 17002 字,大约阅读时间需要 56 分钟。

目录


 一、分页

试问如果当数据量特别大的时候,你是怎么解决分页的?

  • 方式a、记录当前访问页数的数据id
  • 方式b、最多显示120页等
  • 方式c、只显示上一页,下一页,不让选择页码,对页码进行加密

1、基于limit offset 做分页

from rest_framework.pagination import LimitOffsetPagination
1 urlpatterns = [2     url(r'^admin/', admin.site.urls),3     url(r'^app01/(?P
[v1|v2]+)/', include('app01.urls'))4 5 ]
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 8 ]
app01.url
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  # 最大限制默认是None10     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 = code29         self.data = data30         self.error = error31 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.data41             ret.next = p1.get_next_link()42         except Exception as e:43             ret.code= 100144             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 = 511 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)
views.py

3、基于Cursor的分页

     2可能存在性能问题,如果用户吧page给改的很大,查询速度就会很慢。还有一种页码加密的方式,

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 = 311 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,现在我们来了解一下其他的类,其中1、3、4用到的最多

需要导入的类

from rest_framework.views import APIViewfrom rest_framework.generics import GenericAPIViewfrom rest_framework.viewsets import GenericViewSetfrom 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)
APIView

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 = MySerializes15     pagination_class = P116     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)
GenericAPIView

3、 GenericViewSet(ViewSetMixin, generics.GenericAPIView)

增    POST    /users/删    DELETE    /users/1/改   #全部修改    PUT    /users/1/    #局部修改    patch    /users/1/查    GET    /users/     GET    /users/1/ 在GET请求的时候如果带ID说明查一条,如果不带则查所有

原始的

1 urlpatterns = [2 3     url(r'^index/$', views.IndexView.as_view()),4     url(r'^index/(?P
\d+)$', views.IndexView.as_view()),5 ]
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         pass12 13     def put(self,request,*args,**kwargs):14         pass15 16     def patch(self,request,*args,**kwargs):17         pass18 19     def delete(self,request,*args,**kwargs):20                 pass
views.py

用了GenericViewSet这种方式的时候注意url变了

1 urlpatterns = [2     url(r'^index3/$', views.IndexView3.as_view({
'get': 'list','post':'create'})),3 url(r'^index3/(?P
\d+)/$', views.IndexView3.as_view({
'get': 'retrieve'})),4 5 ]
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')
GenericViewSet

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
[a-z0-9]+)/', views.IndexView4.as_view({
'get': 'list','post':'create'})), #.json想让页面上显示成json格式5 url(r'^index4/(?P
\d+)/', views.IndexView4.as_view({
'get': 'retrieve', 'delete': 'destroy','put':'partial_update'})), #查看单条,删除,修改数据6 url(r'^index4(?P
\d+)\.(?P
[a-z0-9]+)/', views.IndexView4.as_view({
'get': 'retrieve', 'delete': 'destroy','put':'partial_update'})),7 8 ]
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.UserInfo12         fields = "__all__"13 14 class IndexView4(ModelViewSet):15     queryset = models.UserInfo.objects.all()16     serializer_class = IndexSerializer17     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.UserInfo11         fields = "__all__"12 13 class IndexView4(ModelViewSet):14     queryset = models.UserInfo.objects.all()15     serializer_class = IndexSerializer16     pagination_class = P217 18     def list(self, request, *args, **kwargs):19         '''获取get请求的所有'''20         pass21 22     def retrieve(self, request, *args, **kwargs):23         '''查看单条数据'''24         pass25     def destroy(self, request, *args, **kwargs):26         '''删除DELETE'''27         pass28     def create(self, request, *args, **kwargs):29         '''添加数据POST'''30         pass31     def update(self, request, *args, **kwargs):32         '''全部修改PUT'''33         pass34     def partial_update(self, request, *args, **kwargs):35         '''局部修改PATCH'''36         pass
基于ModelViewSet自定制

继承关系

 

三、路由

第一类:自定义路由

# http://127.0.0.1:8000/api/v1/auth/url(r'^auth/$', views.AuthView.as_view()),# http://127.0.0.1:8000/api/v1/auth.json # 想要让页面显示json格式url(r'^auth\.(?P
[a-z0-9]+)$', views.AuthView.as_view()),# http://127.0.0.1:8000/api/v1/auth/1/url(r'^auth/(?P
\d+)/$', views.AuthView.as_view()),# http://127.0.0.1:8000/api/v1/auth/1.jsonurl(r'^auth/(?P
\d+)\.(?P
[a-z0-9]+)$', views.AuthView.as_view()),class AuthView(views.APIView): def get(self,request,*args,**kwargs): return Response('...')

第二类:半自动路由  IndexView里面需要有和路由参数对应的方法

url(r'^index/$', views.IndexView.as_view({
'get':'list','post':'create'})),url(r'^index\.(?P
[a-z0-9]+)$', views.IndexView.as_view({
'get':'list','post':'create'})),url(r'^index/(?P
\d+)/$', views.IndexView.as_view({
'get':'retrieve','delete':'destroy','put':'update','patch':'partial_update'})),url(r'^index(?P
\d+)\.(?P
[a-z0-9]+)$', views.IndexView.as_view({
'get':'retrieve','delete':'destroy','put':'update','patch':'partial_update'})),class IndexView(viewsets.ModelViewSet): queryset = models.UserInfo.objects.all() serializer_class = IndexSerializer pagination_class = P2

第三类:全自动路由,会自动生成四个url

router = DefaultRouter()router.register('index',views.IndexViewSet)urlpatterns = [    url(r'^', include(router.urls)),]class IndexViewSet(viewsets.ModelViewSet):    queryset = models.UserInfo.objects.all()    serializer_class = IndexSerializer    pagination_class = P2            class IndexSerializer(serializers.ModelSerializer):    class Meta:        model = models.UserInfo        fields = "__all__"

四、渲染器

根据 用户请求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/ 
1 from django.conf.urls import url, include2 from web.views import s11_render3 4 urlpatterns = [5     url(r'^test/$', s11_render.TestView.as_view()),6     url(r'^test\.(?P
[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  7 from rest_framework.renderers import JSONRenderer 8  9 from .. import models10 11 12 class TestSerializer(serializers.ModelSerializer):13     class Meta:14         model = models.UserInfo15         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 models10 11 12 class TestSerializer(serializers.ModelSerializer):13     class Meta:14         model = models.UserInfo15         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、 Form表单

访问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 HTMLFormRenderer10 11 from .. import models12 13 14 class TestSerializer(serializers.ModelSerializer):15     class Meta:16         model = models.UserInfo17         fields = "__all__"18 19 20 class TestView(APIView):21     renderer_classes = [HTMLFormRenderer, ]22 23     def get(self, request, *args, **kwargs):24         user_list = models.UserInfo.objects.all().first()25         ser = TestSerializer(instance=user_list, many=False)26         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, include2 from web.views import s11_render3 4 urlpatterns = [5     url(r'^test/$', s11_render.TestView.as_view()),6     url(r'^test\.(?P
[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 11 class TestSerializer(serializers.ModelSerializer):12     class Meta:13         model = models.UserInfo14         fields = "__all__"15 16 17 class TestView(APIView):18     renderer_classes = [TemplateHTMLRenderer, ]19 20     def get(self, request, *args, **kwargs):21         user_list = models.UserInfo.objects.all().first()22         ser = TestSerializer(instance=user_list, many=False)23         return Response(ser.data, template_name='user_detail.html')
views.py
1  2  3  4     
5 Title 6 7 8 {
{ user }} 9 {
{ pwd }}10 {
{ ut }}11 12
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 models11 12 13 class TestSerializer(serializers.ModelSerializer):14     class Meta:15         model = models.UserInfo16         fields = "__all__"17 18 19 class CustomBrowsableAPIRenderer(BrowsableAPIRenderer):20     def get_default_renderer(self, view):21         return JSONRenderer()22 23 24 class TestView(APIView):25     renderer_classes = [CustomBrowsableAPIRenderer, ]26 27     def get(self, request, *args, **kwargs):28         user_list = models.UserInfo.objects.all().first()29         ser = TestSerializer(instance=user_list, many=False)30         return Response(ser.data, template_name='user_detail.html')
views.py

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

 

转载于:https://www.cnblogs.com/morgana/p/8496371.html

你可能感兴趣的文章
源码阅读 - java.util.concurrent (三)ConcurrentHashMap
查看>>
Daily Scrum 10.30
查看>>
SQL语言之概述(一)
查看>>
数据库表 copy
查看>>
LinkedList源码解析
查看>>
SignalR循序渐进(一)简单的聊天程序
查看>>
MyServer
查看>>
Learning Cocos2d-x for XNA(2)——深入剖析Hello World
查看>>
软件建模——第9章 毕业论文管理系统—面向对象方法
查看>>
Http协议
查看>>
手机端web开发必备代码
查看>>
[SDOI2008]洞穴勘测
查看>>
NOI2014 购票
查看>>
Difference between Linearizability and Serializability
查看>>
电影《绿皮书》
查看>>
IDEA使用操作文档
查看>>
如何对网课、游戏直播等进行录屏
查看>>
UIView
查看>>
有关去掉谷歌及火狐浏览器文本框 数字类型 上下箭头的方法
查看>>
MySQL数据迁移到SQL Server
查看>>