目录

一、分页

二、视图

三、路由

四、渲染器


一、分页

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

  • 方式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. 原生JS日历 + JS格式化时间格式

    公司项目中用到,以前没做过,废了好几个小时 终于做好了 先来效果图(暂时没写样式 凑合着看吧) 点击左右按钮都能改变月份 下方表格中的数据也会跟着变化 贴上代码 : html部分: <div s ...

  2. 【sparkStreaming】将DStream保存在MySQL

    package SparkDemo import java.sql.{Connection, DriverManager, PreparedStatement} import org.apache.s ...

  3. MySQL 5.6 二进制包安装配置多实例方法

    MySQL支持一台机器上启动多个实例,如果你的机器性能很好的话,启动多个实例将最大化利用你的服务器硬件资源. MySQL多实例一般有两种配置方法: 1.官方推荐的mysqld_multi方式,多个实例 ...

  4. ajax用json实现数据传输

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族 ...

  5. Compiling OpenGL games with the Flash C Compiler (FlasCC)

    Compiling OpenGL games with the Flash C Compiler (FlasCC) In this article I show how to use the Flas ...

  6. python学习之控制语句

    #if statement number=int(input("please input a number")); if number<10 : print("is ...

  7. poj 3517

    题目链接  http://poj.org/problem?id=3517 题意        约瑟夫环  要求最后删掉的那个人是谁: 方法        理解递推公式就行了  考虑这样一组数据  k ...

  8. vector释放内存之swap方法

    相信大家看到swap这个词都一定不会感到陌生,就是简单的元素交换.但swap在C++ STL中散发着无穷的魅力.下面将详细的说明泛型算法swap和容器中的swap成员函数的使用! 1. 泛型算法swa ...

  9. Servlet中的Filter(过滤器)

     Filter,过滤器,是处于客户端与服务器资源文件之间的一道过滤网,在访问资源文件之前,通过一系列的过滤器对请求进行修改.判断等,把不符合规则的请求在中途拦截或修改.也可以对响应进行过滤,拦截或修改 ...

  10. 关于JS浅拷贝和深拷贝

    在 JS 中有一些基本类型像是Number.String.Boolean,而对象就是像这样的东西{ name: 'Larry', skill: 'Node.js' },对象跟基本类型最大的不同就在于他 ...