Django Rest Framework 4
目录
一、分页
试问如果当数据量特别大的时候,你是怎么解决分页的?
- 方式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的更多相关文章
- 使用django rest framework
django 刚接触,想做一些restful api , google了一下,发现有现成的框架.Django REST framework. 对使用做下记录: 安装 从http://django-re ...
- 利用 Django REST framework 编写 RESTful API
利用 Django REST framework 编写 RESTful API Updateat 2015/12/3: 增加 filter 最近在玩 Django,不得不说 rest_framewor ...
- django rest framework 入门
django rest framework 入门1-序列化 Serialization 分类: Python 2013-01-22 22:24 11528人阅读 评论(0) 收藏 举报 djangop ...
- django rest framework
Django-Rest-Framework 教程: 4. 验证和权限 作者: Desmond Chen, 发布日期: 2014-06-01, 修改日期: 2014-06-02 到目前为止, 我们的AP ...
- django rest framework csrf failed csrf token missing or incorrect
django rest framework csrf failed csrf token missing or incorrect REST_FRAMEWORK = { 'DEFAULT_AUTHEN ...
- Django REST Framework学习——Android使用REST方法访问Diango
本文更应该叫做Android如何模拟浏览器访问Django服务器后台. 环境为: Android通过HttpClient访问服务器,从Django中获取json数据,解析显示在UI界面上. 问题为: ...
- 用Django Rest Framework和AngularJS开始你的项目
Reference: http://blog.csdn.net/seele52/article/details/14105445 译序:虽然本文号称是"hello world式的教程&quo ...
- Django REST framework使用ViewSets的自定义路由实现过程
在Django中使用基于类的视图(ClassView),类中所定义的方法名称与Http的请求方法相对应,才能基于路由将请求分发(dispatch)到ClassView中的方法进行处理,而Django ...
- Django REST FrameWork中文教程2:请求和响应
从这一点开始,我们将真正开始覆盖REST框架的核心.我们来介绍几个基本的构建块. 请求对象REST框架引入了Request扩展常规的对象HttpRequest,并提供更灵活的请求解析.Request对 ...
- Django REST framework 中文教程1:序列化
建立环境 在我们做任何事情之前,我们将使用virtualenv创建一个新的虚拟环境.这将确保我们的包配置与我们正在开展的任何其他项目保持良好的隔离. virtualenv envsource env/ ...
随机推荐
- C++空类和string类
1. 空类 1.1 空类默认哪六个成员函数. class Empty { public: Empty(); //缺省构造函数 Empty e; Empty( const Empty& ); / ...
- LeetCode OJ:3Sum Closest(最接近的三数之和)
Given an array S of n integers, find three integers in S such that the sum is closest to a given num ...
- Java(Android)线程池妙用
介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new T ...
- AndroidManifest.xml activity属性设置大全
1.android:allowTaskReparenting=["true"|"false"] 是否允许activity更换从属的任务,比如从短信息任务切换到浏 ...
- Castle IOC概念理解
最近在用Castle,里面有些概念比较容易混淆,特此解释一下: 1. 容器(Container):Windsor是一个反转控制容器.它创建在一个微内核的基础之上,这个微内核能够扫描类并且试图找到这些类 ...
- How your script code be coverted into arm code and running on ios.
Your script code is compiled into DLLs (assemblies) by the editor. When you build for iOS, these ass ...
- [QT][SQLITE][QTDEMO]qt5.8_sqlite数据库_demo
qt环境:5.8 数据库:sqlite //-------------------------------------- sqlite 日期 搜索 -------------------------- ...
- 【MFC】MFC DLEdit 设计属于自己的编辑框_鼠标悬停
MFC DLEdit 设计属于自己的编辑框 2012-02-04 13:00 by 捣乱小子, 3543 阅读, 5 评论, 收藏, 编辑 起因 无意间看到了大牛们写的自定义编辑框控件,于是找了个时间 ...
- linux 下看所有用户 及所有组
俺的centos vps上面不知道添加了多少个账户,今天想清理一下,但是以前还未查看过linux用户列表,google了一下,找到方便的放:一般情况下是 cat /etc/passwd 可以查看所有用 ...
- vue前端开发那些事——前言
如上图所示,用vue开发一个小型网站所涉及到的知识点.这只是前端部分已经这么多了.接下来我分解开来说. 1.Node 当我们开发vue项目的时候,首先要安装Node.js,那么我们即使当时不理解为什么 ...