Django Rest Framework(分页、视图、路由、渲染器)
一、分页
试问如果当数据量特别大的时候,你是怎么解决分页的?
- 方式a、记录当前访问页数的数据id
- 方式b、最多显示120页等
- 方式c、只显示上一页,下一页,不让选择页码,对页码进行加密
1、基于limit offset 做分页(如:在url后面加上?offset=0&limit=2,即代表从第0条开始,往后取2条(即1,2))
from rest_framework.pagination import LimitOffsetPagination
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^app01/(?P<version>[v1|v2]+)/', include('app01.urls')) ]
urls.py
urlpatterns = [
url(r'^index1/', views.IndexView1.as_view()),
url(r'^index2/', views.IndexView2.as_view()),
url(r'^index3/', views.IndexView3.as_view()),
url(r'^index4/', views.IndexView4.as_view()),
url(r'^index5/', views.IndexView5.as_view()), ]
app01.url
from rest_framework.views import APIView
from rest_framework.response import Response
from app01.serializes.myserializes import MySerializes
from rest_framework.pagination import LimitOffsetPagination
from app01 import models # =========== 可以自己进行自定制分页,基于limitoffset===================
class P1(LimitOffsetPagination):
max_limit = 3 # 最大显示3条数据,当取的条数超过3条时,只显示前3条,不会再显示后面的,这个值默认是None,即不做限制
default_limit =2 # 设置每一页显示多少条
limit_query_param = 'limit' # 往后取几条
offset_query_param = 'offset' # 当前所在的位置 class IndexView2(APIView):
#使用http://127.0.0.1:8080/app01/v1/index2/?offset=2&limit=4可进行判断
def get(self,request,*args,**kwargs):
user_list = models.UserInfo.objects.all()
p1 = P1()#注册分页
page_user_list = p1.paginate_queryset(queryset=user_list,request=request,view=self)
print('打印的是分页的数据',page_user_list)
ser = MySerializes(instance=page_user_list,many=True) #可允许多个
# return Response(ser.data) #不含上一页下一页
return p1.get_paginated_response(ser.data) =======================也可以用下面这种形式===========
class BaseResponse(object):
def __init__(self,code=1000,data=None,error=None):
self.code = code
self.data = data
self.error = error
class IndexView(views.APIView):
'''第二种类表示的方式'''
def get(self,request,*args,**kwargs):
ret = BaseResponse()
try:
user_list = models.UserInfo.objects.all()
p1 = P1()
page_user_list = p1.paginate_queryset(queryset=user_list,request=request,view=self)
ser = IndexSerializer(instance=page_user_list,many=True)
ret.data = ser.data
ret.next = p1.get_next_link() #下一页链接
except Exception as e:
ret.code= 1001
ret.error = 'xxxx错误'
return Response(ret.__dict__)
views.py
2、基于页码的分页
from rest_framework.pagination import PageNumberPagination
# ======================基于页码实现的分页==============
class P2(PageNumberPagination):
#默认每页显示的数据条数
page_size = 2
#获取url参数中设置的每页显示数据条数
page_size_query_param = 'size'
#获取url中传入的页码key
page_query_param = 'page'
#最大支持的每页显示的数据条数
max_page_size = 5 class IndexView3(APIView):
#使用http://127.0.0.1:8080/app01/v1/index3/?page=1&page_size=1可进行判断
def get(self,request,*args,**kwargs):
user_list = models.UserInfo.objects.all()
#实例化分页对象,获取数据库中的分页数据
p2 = P2()
print(p2.page_size_query_description)
page_user_list = p2.paginate_queryset(queryset=user_list,request=request,view=self)
print('打印的是分页的数据',page_user_list) #序列化对象
ser = MySerializes(instance=page_user_list,many=True) #可允许多个 #生成分页和数据
# return Response(ser.data) #不含上一页下一页
return p2.get_paginated_response(ser.data) # 是Response对象,有上一页下一页
views.py
3、基于Cursor的分页
2可能存在性能问题,如果用户吧page给改的很大,查询速度就会很慢。还有一种页码加密的方式,
# =====================基于Cursor的分页============
class P3(CursorPagination):
# URL传入的游标参数
cursor_query_param = 'cursor'
# 默认每页显示的数据条数
page_size = 2
# URL传入的每页显示条数的参数
page_size_query_param = 'size'
# 每页显示数据最大条数
max_page_size = 3 # 根据ID从大到小排列
ordering = "id" class IndexView4(APIView):
#使用http://127.0.0.1:8080/app01/v1/index4/?cursor=cj0xJnA9NA%3D%3D&size=3可进行判断
def get(self,request,*args,**kwargs):
user_list = models.UserInfo.objects.all().order_by('-id')
p3 = P3()#注册分页
page_user_list = p3.paginate_queryset(queryset=user_list,request=request,view=self)
print('打印的是分页的数据',page_user_list)
ser = MySerializes(instance=page_user_list,many=True) #可允许多个
# return Response(ser.data) #不含上一页下一页
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
class IndexView2(APIView):
def get(self,request,*args,**kwargs):
user_list = models.UserInfo.objects.all()
ser = MySerializes(instance=user_list,many=True)
return Response(ser.data)
APIView
2、GenericAPIView(APIView)
from rest_framework.response import Response
from rest_framework.generics import GenericAPIView
from app01 import models
from app01.serializes.myserializes import MySerializes
from rest_framework.pagination import LimitOffsetPagination
class P1(LimitOffsetPagination):
max_limit = 3 # 最大限制默认是None
default_limit =2 # 设置每一页显示多少条
limit_query_param = 'limit' # 往后取几条
offset_query_param = 'offset' # 当前所在的位置 class IndexView1(GenericAPIView):
queryset = models.UserInfo.objects.all()
serializer_class = MySerializes
pagination_class = P1
def get(self,request,*args,**kwargs):
user_list = self.get_queryset()
p1 = P1() #注册分页
data = p1.paginate_queryset(queryset=user_list,request=request,view=self) #获取分页的数据
ser = self.get_serializer(instance=data,many=True) #序列化
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说明查一条,如果不带则查所有
原始的
urlpatterns = [
url(r'^index/$', views.IndexView.as_view()),
url(r'^index/(?P<pk>\d+)$', views.IndexView.as_view()),
]
urls.py
class IndexView(views.APIView):
def get(self,request,*args,**kwargs):
pk = kwargs.get('pk')
if pk:
pass # 获取单条信息
else:
pass # 获取列表信息
def post(self,request,*args,**kwargs):
pass
def put(self,request,*args,**kwargs):
pass
def patch(self,request,*args,**kwargs):
pass
def delete(self,request,*args,**kwargs):
pass
views.py
用了GenericViewSet这种方式的时候注意url变了
urlpatterns = [
url(r'^index3/$', views.IndexView3.as_view({'get': 'list','post':'create'})), #get方式执行list函数,post方式执行create函数
url(r'^index3/(?P<pk>\d+)/$', views.IndexView3.as_view({'get': 'retrieve'})), #get方式执行retrieve函数 ]
urls.py
class IndexView3(GenericViewSet):
queryset = models.UserInfo.objects.all()
serializer_class = MySerializes
pagination_class = P1 def list(self,request,*args,**kwargs):
#获取列表信息
return Response('...') def retrieve(self,request,*args,**kwargs):
#获取单条数据
return Response('xxx')
GenericViewSet
4、 ModelViewSet(mixins.CreateModelMixin,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin,mixins.ListModelMixin,GenericViewSet)
利用ModelViewSet增删改查不用自己写了,内部把增删改查都干了,当满足不了需求的时候我们也可以自定制
urlpatterns = [
url(r'^index4/', views.IndexView4.as_view({'get': 'list','post':'create'})), #获取数据和添加数据
url(r'^index4\.(?P<format>[a-z0-9]+)/', views.IndexView4.as_view({'get': 'list','post':'create'})), #.json想让页面上显示成json格式
url(r'^index4/(?P<pk>\d+)/', views.IndexView4.as_view({'get': 'retrieve', 'delete': 'destroy','put':'partial_update'})), #查看单条,删除,修改数据
url(r'^index4(?P<pk>\d+)\.(?P<format>[a-z0-9]+)/', views.IndexView4.as_view({'get': 'retrieve', 'delete': 'destroy','put':'partial_update'})),
]
urls.py
注意啦:用ModelSerializer这种方法必须要用IndexSerializer(ModelSerializer)这种方式序列化
class P2(PageNumberPagination):
page_size = 3 #每一页显示的条数
page_query_param = 'page' #获取参数中传入的页码
page_size_query_param = 'size' #获取url参数中每页显示的数据条数 max_page_size = 5 class IndexSerializer(ModelSerializer):
class Meta:
model = models.UserInfo
fields = "__all__" class IndexView4(ModelViewSet):
queryset = models.UserInfo.objects.all()
serializer_class = IndexSerializer
pagination_class = P2
views.py
自定制
class P2(PageNumberPagination):
page_size = 3 #每一页显示的条数
page_query_param = 'page' #获取参数中传入的页码
page_size_query_param = 'size' #获取url参数中每页显示的数据条数 max_page_size = 5 class IndexSerializer(ModelSerializer):
class Meta:
model = models.UserInfo
fields = "__all__" class IndexView4(ModelViewSet):
queryset = models.UserInfo.objects.all()
serializer_class = IndexSerializer
pagination_class = P2 def list(self, request, *args, **kwargs):
'''获取get请求的所有'''
pass def retrieve(self, request, *args, **kwargs):
'''查看单条数据'''
pass
def destroy(self, request, *args, **kwargs):
'''删除DELETE'''
pass
def create(self, request, *args, **kwargs):
'''添加数据POST'''
pass
def update(self, request, *args, **kwargs):
'''全部修改PUT'''
pass
def partial_update(self, request, *args, **kwargs):
'''局部修改PATCH'''
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('...')
第二类:半自动路由
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/
from django.conf.urls import url, include
from web.views import s11_render urlpatterns = [
url(r'^test/$', s11_render.TestView.as_view()),
url(r'^test\.(?P<format>[a-z0-9]+)', s11_render.TestView.as_view()),
]
urls.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers from rest_framework.renderers import JSONRenderer from .. import models class TestSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserInfo
fields = "__all__" class TestView(APIView):
renderer_classes = [JSONRenderer, ] def get(self, request, *args, **kwargs):
user_list = models.UserInfo.objects.all()
ser = TestSerializer(instance=user_list, many=True)
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/
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers from rest_framework.renderers import AdminRenderer from .. import models class TestSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserInfo
fields = "__all__" class TestView(APIView):
renderer_classes = [AdminRenderer, ] def get(self, request, *args, **kwargs):
user_list = models.UserInfo.objects.all()
ser = TestSerializer(instance=user_list, many=True)
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/
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers from rest_framework.renderers import JSONRenderer
from rest_framework.renderers import AdminRenderer
from rest_framework.renderers import HTMLFormRenderer from .. import models class TestSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserInfo
fields = "__all__" class TestView(APIView):
renderer_classes = [HTMLFormRenderer, ] def get(self, request, *args, **kwargs):
user_list = models.UserInfo.objects.all().first()
ser = TestSerializer(instance=user_list, many=False)
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/
from django.conf.urls import url, include
from web.views import s11_render urlpatterns = [
url(r'^test/$', s11_render.TestView.as_view()),
url(r'^test\.(?P<format>[a-z0-9]+)', s11_render.TestView.as_view()),
]
urls.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from rest_framework.renderers import TemplateHTMLRenderer from .. import models class TestSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserInfo
fields = "__all__" class TestView(APIView):
renderer_classes = [TemplateHTMLRenderer, ] def get(self, request, *args, **kwargs):
user_list = models.UserInfo.objects.all().first()
ser = TestSerializer(instance=user_list, many=False)
return Response(ser.data, template_name='user_detail.html')
views.py
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{{ user }}
{{ pwd }}
{{ ut }}
</body>
</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/
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers from rest_framework.renderers import JSONRenderer
from rest_framework.renderers import BrowsableAPIRenderer from .. import models class TestSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserInfo
fields = "__all__" class CustomBrowsableAPIRenderer(BrowsableAPIRenderer):
def get_default_renderer(self, view):
return JSONRenderer() class TestView(APIView):
renderer_classes = [CustomBrowsableAPIRenderer, ] def get(self, request, *args, **kwargs):
user_list = models.UserInfo.objects.all().first()
ser = TestSerializer(instance=user_list, many=False)
return Response(ser.data, template_name='user_detail.html')
views.py
注意:如果同时多个存在时,自动根据URL后缀来选择渲染器。
Django Rest Framework(分页、视图、路由、渲染器)的更多相关文章
- Django-RestFrameWork之分页 视图 路由 渲染器
目录 一.分页 二.视图 三.路由 四.渲染器 一.分页 试问如果当数据量特别大的时候,你是怎么解决分页的? 方式a.记录当前访问页数的数据id 方式b.最多显示120页等 方式c.只显示上一页,下一 ...
- Django rest framework(8)---- 视图和渲染器
django rest framework 之视图 序列化器 PagerSerialiser from rest_framework import serializers from api im ...
- Django Rest framework 之 视图
RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...
- django: django rest framework 分页
django: django rest framework 分页 2018年06月22日 13:41:43 linux_player_c 阅读数:665更多 所属专栏: django 实战 版权声 ...
- Django rest framework(5)----解析器
目录 Django rest framework(1)----认证 Django rest framework(2)----权限 Django rest framework(3)----节流 Djan ...
- Django REST Framework - 分页 - 渲染器 - 解析器
为什么要使用分页? 我们数据表中可能会有成千上万条数据,当我们访问某张表的所有数据时,我们不太可能需要一次把所有的数据都展示出来,因为数据量很大,对服务端的内存压力比较大还有就是网络传输过程中耗时也会 ...
- Django rest framework (视图类详解)
官网:https://www.django-rest-framework.org/api-guide/viewsets/ 在django rest framework 视图中一共有N个类 第一类:AP ...
- 05 Django REST Framework 分页
01-分页模式 rest framework中提供了三种分页模式: from rest_framework.pagination import PageNumberPagination, LimitO ...
- DRF (Django REST framework) 中的路由Routers
路由Routers 注意是:对于视图集ViewSet!!!我们除了可以自己手动指明请求方式与动作action之间的对应关系外,还可以使用Routers来帮助我们快速实现路由信息. REST frame ...
随机推荐
- 用10张图来看机器学习Machine learning in 10 pictures
I find myself coming back to the same few pictures when explaining basic machine learning concepts. ...
- Error: Finish can only be called once
Android studio 启动或者新建项目:报错“Error: Finish can only be called once” gradle缓存问题: 默认的额缓存路径在: on windows ...
- C#文本文件(.txt)读写 [转]
目录 前言 读取txt文件 写入txt文件 前言 计算机在最初只支持ASCII编码,但是后来为了支持其他语言中的字符(比如汉字)以及一些特殊字符(比如€),就引入了Unicode字符集.基于Unico ...
- 如何获得Windows Server 2012上的FC的WWN
我有一个测试环境, 一对Host与storage array之间既有iSCSI的连接, 也有FC的连接. 原来iSCSI的连接是OK的, 现在需要转用FC. 当在光纤交换机上划好了Zone之后, st ...
- vs中debug和release的区别你知道吗
在Visual Studio中,生成应用程序的时候有2种模式:Debug和Release.两者之间如何取舍呢? 一.vs中debug和release的区别 1.Debug 通常称为调试版本,它包含调试 ...
- poj 1260 Pearls 斜率优化dp
这个题目数据量很小,但是满足斜率优化的条件,可以用斜率优化dp来做. 要注意的地方,0也是一个决策点. #include <iostream> #include <cstdio> ...
- 转: SSH 公钥认证
转: http://blog.knownsec.com/2012/05/ssh-%E5%85%AC%E9%92%A5%E8%AE%A4%E8%AF%81/ SSH 公钥认证 2012-05-15 简介 ...
- linux apache服务器优化建议整理(很实用)
转载:http://www.cnblogs.com/zhongbin/archive/2013/06/11/3131865.html 1.apache服务器的time_wait过多 fin_wait1 ...
- javascript - 字符串比较
1. sort是排序根据字符的ASCIll码排序的,不分字符串或其它元素(仅适用于数组) 2. split是将字符串转为数组形式 3. join是将数组转为字符串形式 4. indexOf找到元素后返 ...
- vue - router 起步
官方API:https://router.vuejs.org/zh/guide/#javascript vue-cli for index.js export default new Router({ ...