目录

一、分页

二、视图

三、路由

四、渲染器


一、分页

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

  • 方式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<version>[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 # 最大限制默认是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)

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

需要导入的类

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)

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 = 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)

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<pk>\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 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这种方式的时候注意url变了

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
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<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 ]

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

基于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<format>[a-z0-9]+)$', views.AuthView.as_view()),
# http://127.0.0.1:8000/api/v1/auth/1/
url(r'^auth/(?P<pk>\d+)/$', views.AuthView.as_view()),
# http://127.0.0.1:8000/api/v1/auth/1.json
url(r'^auth/(?P<pk>\d+)\.(?P<format>[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<format>[a-z0-9]+)$', views.IndexView.as_view({'get':'list','post':'create'})),
url(r'^index/(?P<pk>\d+)/$', views.IndexView.as_view({'get':'retrieve','delete':'destroy','put':'update','patch':'partial_update'})),
url(r'^index(?P<pk>\d+)\.(?P<format>[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, 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
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、 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 HTMLFormRenderer
10
11 from .. import models
12
13
14 class TestSerializer(serializers.ModelSerializer):
15 class Meta:
16 model = models.UserInfo
17 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, 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
11 class TestSerializer(serializers.ModelSerializer):
12 class Meta:
13 model = models.UserInfo
14 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 <!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
13 class TestSerializer(serializers.ModelSerializer):
14 class Meta:
15 model = models.UserInfo
16 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后缀来选择渲染器。

Django Rest Framework 4的更多相关文章

  1. 使用django rest framework

    django 刚接触,想做一些restful api , google了一下,发现有现成的框架.Django REST framework. 对使用做下记录: 安装 从http://django-re ...

  2. 利用 Django REST framework 编写 RESTful API

    利用 Django REST framework 编写 RESTful API Updateat 2015/12/3: 增加 filter 最近在玩 Django,不得不说 rest_framewor ...

  3. django rest framework 入门

    django rest framework 入门1-序列化 Serialization 分类: Python 2013-01-22 22:24 11528人阅读 评论(0) 收藏 举报 djangop ...

  4. django rest framework

    Django-Rest-Framework 教程: 4. 验证和权限 作者: Desmond Chen, 发布日期: 2014-06-01, 修改日期: 2014-06-02 到目前为止, 我们的AP ...

  5. django rest framework csrf failed csrf token missing or incorrect

    django rest framework csrf failed csrf token missing or incorrect REST_FRAMEWORK = { 'DEFAULT_AUTHEN ...

  6. Django REST Framework学习——Android使用REST方法访问Diango

    本文更应该叫做Android如何模拟浏览器访问Django服务器后台. 环境为: Android通过HttpClient访问服务器,从Django中获取json数据,解析显示在UI界面上. 问题为: ...

  7. 用Django Rest Framework和AngularJS开始你的项目

    Reference: http://blog.csdn.net/seele52/article/details/14105445 译序:虽然本文号称是"hello world式的教程&quo ...

  8. Django REST framework使用ViewSets的自定义路由实现过程

    在Django中使用基于类的视图(ClassView),类中所定义的方法名称与Http的请求方法相对应,才能基于路由将请求分发(dispatch)到ClassView中的方法进行处理,而Django ...

  9. Django REST FrameWork中文教程2:请求和响应

    从这一点开始,我们将真正开始覆盖REST框架的核心.我们来介绍几个基本的构建块. 请求对象REST框架引入了Request扩展常规的对象HttpRequest,并提供更灵活的请求解析.Request对 ...

  10. Django REST framework 中文教程1:序列化

    建立环境 在我们做任何事情之前,我们将使用virtualenv创建一个新的虚拟环境.这将确保我们的包配置与我们正在开展的任何其他项目保持良好的隔离. virtualenv envsource env/ ...

随机推荐

  1. 如何拿到半数面试公司Offer——我的Python求职之路(转载)

    从八月底开始找工作,短短的一星期多一些,面试了9家公司,拿到5份Offer,可能是因为我所面试的公司都是些创业性的公司吧,不过还是感触良多,因为学习Python的时间还很短,没想到还算比较容易的找到了 ...

  2. Template pattern模板方法模式

    1>模板模式定义了算法的步骤,把这些步骤的实现延续到子类 2>模板模式为我们提供了一个代码复用的技巧 3>模板抽象类中可以定义具体方法.抽象方法和钩子方法 4>为了防止子类改变 ...

  3. JSON.stringify的三个参数

    前段时间勾股有提到stringify是支持三个参数,刷新的了我的认知,后来查到文档才发现还真的是支持三个参数的. 参考资料: stringify stringify方法顾名思义,就是把JSON序列换, ...

  4. http keep - alive 与 长连接

    http1.0 2.0 1.1区别 你可以把 WebSocket 看成是 HTTP 协议为了支持长连接所打的一个大补丁,它和 HTTP 有一些共性,是为了解决 HTTP 本身无法解决的某些问题而做出的 ...

  5. Linux系统下的shutdown命令用于安全的关闭/重启计算机

    Linux系统下的shutdown命令用于安全的关闭/重启计算机,它不仅可以方便的实现定时关机,还可以由用户决定关机时的相关参数.在执行shutdown命令时,系统会给每个终端(用户)发送一条屏显,提 ...

  6. Build ios app with Delphi Xe4. Lazy Social Talker ready for sale.

    Yes, it is build with Delphi XE4. try it. now. What is  Lazy Social  Talker? Lazy Social Talker is a ...

  7. grep 常用正则匹配

    1.或操作 grep -E '123|abc' filename // 找出文件(filename)中包含123或者包含abc的行 egrep '123|abc' filename // 用egrep ...

  8. MyBatis典型的错误org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)

    XXXmapper.java(接口) XXXmapper.xml(结果集映射) //此两个文件要在统一包下,且xml中的namespace是唯一的,为了区分须写成 该xml的全路径

  9. Linux fork exec等

    http://www.cnblogs.com/leoo2sk/archive/2009/12/11/talk-about-fork-in-linux.html http://www.cnblogs.c ...

  10. 【spring源码学习】springMVC之映射,拦截器解析,请求数据注入解析,DispatcherServlet执行过程

    [一]springMVC之url和bean映射原理和源码解析 映射基本过程 (1)springMVC配置映射,需要在xml配置文件中配置<mvc:annotation-driven >  ...