DRF url控制 解析器 响应器 版本控制 分页(常规分页,偏移分页,cursor游标分页)...
url控制 |
第二种写法(只要继承了ViewSetMixin)
url(r'^pub/$',views.Pub.as_view({'get':'list','post':'create'})), #获取所有记得路由后面加$结束符 #pub/?format=jsonurl(r'^pub\.(?P<format>\w+)$',views.Pub.as_view({'get':'list','post':'create'})), #pub.jsonurl(r'^pub/(?P<pk>\d+)$',views.Pub.as_view({'get':'retrieve','put':'update','delete':'destroy'})), #获取一条
第三种(自动生成路由,必须继承ModelViewSet)
from django.conf.urls import url,include
SimpleRouter 自动生成两条路由
from rest_framework.routers import SimpleRouter,DefaultRouter #路由控制 router = SimpleRouter() router.register('pub',views.Pub)urlpatterns = [url(r'^admin/', admin.site.urls),#其他路由 url(r'',include(router.urls)),]
DefaultRouter自动生成四条路由
from rest_framework.routers import SimpleRouter,DefaultRouter #路由控制 router = DefaultRouter() router.register('pub',views.Pub)urlpatterns = [url(r'^admin/', admin.site.urls),#其他路由url(r'',include(router.urls)),]
解析器(一般不需要动,项目最开始全局配置一下就可以了) |
作用:控制视图类能够解析前端传过来的格式是什么样的 (默认配置三种都有) 有application/json,x-www-form-urlencoded,form-data等格式
全局使用:在settings中配置:
REST_FRAMEWORK = {"DEFAULT_PARSER_CLASSES":['rest_framework.parsers.JSONParser',] }
局部使用:
from rest_framework.parsers import JSONParser,FormParser,MultiPartParser,FileUploadParser#json字典 urlencoded form-data 文件
在视图类中
parser_classes=[JSONParser,]
源码流程
当调用request.data的时候去执行解析方法
-->根据传过来的编码方式选择一个解析器对象
--->调用解析器对象的parser方法完成解析
在调用request.data时,才进行解析,由此入手@propertydef data(self):if not _hasattr(self, '_full_data'):self._load_data_and_files()return self._full_data 查看self._load_data_and_files()方法---->self._data, self._files = self._parse()def _parse(self):#用户请求头里content_type的值media_type = self.content_type#self.parsers 就是用户配置的parser_classes = [FileUploadParser,FormParser ]#self里就有content_type,传入此函数parser = self.negotiator.select_parser(self, self.parsers) 查看self.negotiator.select_parser(self, self.parsers)def select_parser(self, request, parsers):#同过media_type和request.content_type比较,来返回解析器,然后调用解析器的解析方法#每个解析器都有media_type = 'multipart/form-data'属性for parser in parsers:if media_type_matches(parser.media_type, request.content_type):return parserreturn None 最终调用parser的解析方法来解析parsed = parser.parse(stream, media_type, self.parser_context)
源码注释
Request实例化,parsers=self.get_parsers()Request(request,parsers=self.get_parsers(),authenticators=self.get_authenticators(),negotiator=self.get_content_negotiator(),parser_context=parser_context) get_parsers方法,循环实例化出self.parser_classes中类对象def get_parsers(self):return [parser() for parser in self.parser_classes] self.parser_classes 先从类本身找,找不到去父类找即APIVIew 中的parser_classes = api_settings.DEFAULT_PARSER_CLASSES api_settings是一个对象,对象里找DEFAULT_PARSER_CLASSES属性,找不到,会到getattr方法def __getattr__(self, attr):if attr not in self.defaults:raise AttributeError("Invalid API setting: '%s'" % attr)try:#调用self.user_settings方法,返回一个字典,字典再取attr属性val = self.user_settings[attr]except KeyError:# Fall back to defaultsval = self.defaults[attr]# Coerce import strings into classesif attr in self.import_strings:val = perform_import(val, attr)# Cache the result self._cached_attrs.add(attr)setattr(self, attr, val)return val user_settings方法 ,通过反射去setting配置文件里找REST_FRAMEWORK属性,找不到,返回空字典@propertydef user_settings(self):if not hasattr(self, '_user_settings'):self._user_settings = getattr(settings, 'REST_FRAMEWORK', {})return self._user_settings
源码注释2
响应器 |
解析成字符串 还是一个浏览器页面
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer #解析成字符串 还是浏览器样式的 # 不用动,就用全局配置即可默认配置中两个都有
全局使用
在settings中配置 settings默认配置中两个都有
REST_FRAMEWORK = {'DEFAULT_PARSER_CLASSES':['rest_framework.parsers.JSONParser',],# 响应器 默认配置两个都由 这个是全局使用 # 'DEFAULT_PARSER_CLASSES':[ 'rest_framework.renderers.JSONRenderer', # 'rest_framework.renderers.BrowsableAPIRenderer',] }
局部使用
在试图类中配置
renderer_classes = [JSONRenderer, BrowsableAPIRenderer]
版本控制 |
作用用于控制版本 视图中 版本问题需要接受版本传过来的参数 注意是单个没有复数
内置版本控制
from rest_framework.versioning import QueryParameterVersioning,AcceptHeaderVersioning,NamespaceVersioning,URLPathVersioning#基于url的get传参方式:QueryParameterVersioning------>如:/users?version=v1 #基于url的正则方式:URLPathVersioning------>/v1/users/ #基于 accept 请求头方式:AcceptHeaderVersioning------>Accept: application/json; version=1.0 #基于主机名方法:HostNameVersioning------>v1.example.com #基于django路由系统的namespace:NamespaceVersioning------>example.com/v1/users/
局部使用
#在CBV类中加入 versioning_class = URLPathVersioning
url中需要写
url(r'(?P<version>[v1|v2])/register/$',views.Register.as_view()),url(r'(?P<version>[v1|v2])/register\.(?P<format>\w+)$',views.Register.as_view()),url(r'(?P<version>[v1|v2])/register/(?P<pk>\d+)$',views.Register.as_view()),
写访问路由的的时候要写上版本
全局使用
在settings中配置
REST_FRAMEWORK = {"DEFAULT_PARSER_CLASSES":['rest_framework.parsers.JSONParser',],'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning','DEFAULT_VERSION': 'v1', # 默认版本(从request对象里取不到,显示的默认值)'ALLOWED_VERSIONS': ['v1', 'v2'], # 允许的版本'VERSION_PARAM': 'version', # URL中获取值的key }
路由不要写
url(r'register/$',views.Register.as_view()),
但是访问路由的时候需要写上版本
在试图类中就可以通过,request.vesrsion取出当前访问哪个版本,相应的去执行相应版本的代码
示例
基于正则的方式
from django.conf.urls import url, include from web.views import TestViewurlpatterns = [url(r'^(?P<version>[v1|v2]+)/test/', TestView.as_view(), name='test'), ]url
View Code
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.versioning import URLPathVersioningclass TestView(APIView):versioning_class = URLPathVersioningdef get(self, request, *args, **kwargs):# 获取版本print(request.version)# 获取版本管理的类print(request.versioning_scheme)# 反向生成URLreverse_url = request.versioning_scheme.reverse('test', request=request)print(reverse_url)return Response('GET请求,响应内容')views.py
View.py
# 基于django内置,反向生成urlfrom django.urls import reverseurl2=reverse(viewname='ttt',kwargs={'version':'v2'})print(url2)
View Code
源码分析
#执行determine_version,返回两个值,放到request对象里 version, scheme = self.determine_version(request, *args, **kwargs) request.version, request.versioning_scheme = version, schemedef determine_version(self, request, *args, **kwargs):#当配置上版本类之后,就会实例化if self.versioning_class is None:return (None, None)scheme = self.versioning_class()return (scheme.determine_version(request, *args, **kwargs), scheme)
分页 |
常规分页 查看第n页 每页显示多少条
#分页 #常规分页 偏移分页 cursor游标分页 from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPaginationclass PublishView(APIView):versioning_class = URLPathVersioningparser_classes = [JSONRenderer,] #解析器def get(self,request,*args,**kwargs):#第一种方法,普通分页'''查询出所有数据实例化产生一个普通分页对象每页显示多少条查询指定查询那一页的key值'''ret= models.Publish.objects.all()page = PageNumberPagination()page.page_size = 3 #每页显示多少条 page.page_query_param = 'page' #按照page名词显示那一页# 前端控制每页显示多少条的查看key值必然要size=9,表示一页显示9条page.page_size_query_param = 'size'#控制每页最大显示多少,size如果传100,最多也是显示10page.max_page_size = 10ret_page = page.paginate_queryset(ret,request,self)#序列化pub_ser = PublishSerlizers(ret_page,many=True)#去settings中配置每页显示多少条 这个是全局配置的话 局部配置全局可以不配置return Response(pub_ser.data)
settings中配置
REST_FRAMEWORK = {# 每页显示两条'PAGE_SIZE':2 }
路由
url(r'^(?P<version>[v1|v2]+)/publish/',views.PublishView.as_view())
serializer
from rest_framework.serializers import ModelSerializer from app01 import models class PublishSerlizers(ModelSerializer):class Meta:model = models.Publishfields = '__all__'
偏移分页 在第n个位置向前向后查询第n个位置
#分页 #常规分页 偏移分页 cursor游标分页 from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPaginationclass PublishView(APIView):versioning_class = URLPathVersioningparser_classes = [JSONRenderer,] #解析器def get(self,request,*args,**kwargs): #偏移分页ret = models.Publish.objects.all()#实例化产生一个偏移分页对象page= LimitOffsetPagination()# 四个参数:# 从标杆位置往后取几个,默认取3个,可以指定page.default_limit = 3# 每条取得条数page.limit_query_param ='limit'# 标杆值,现象偏移到那个位置,如果offset=6, 表示当前在第6条位置上,往后取page.offset_query_param = 'offset'# 最大取10条page.max_limit = 10ret_page = page.paginate_queryset(ret,request,self)#序列化pub_ser= PublishSerlizers(ret_page,many=True)#取settings中配置每页显示多少条return page.get_paginated_response(pub_ser.data)
cursor游标分页
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination class PublishView(APIView):versioning_class = URLPathVersioningparser_classes=[JSONParser,]def get(self, request, *args, **kwargs):ret = models.Publish.objects.all()# 实例化产生一个偏移分页对象page = CursorPagination()#三个参数:#每页显示的大小page.page_size=3#查询的key值page.cursor_query_param='cursor'# 按什么排序page.ordering='id'ret_page = page.paginate_queryset(ret, request, self)# 序列化pub_ser = serializer.PublishSerializers(ret_page, many=True)# 去setting中配置每页显示多少条return page.get_paginated_response(pub_ser.data)
转载于:https://www.cnblogs.com/lakei/p/11143411.html
DRF url控制 解析器 响应器 版本控制 分页(常规分页,偏移分页,cursor游标分页)...相关推荐
- drf 解析器,响应器,路由控制
解析器 作用: 根据请求头 content-type 选择对应的解析器对请求体内容进行处理. 有application/json,x-www-form-urlencoded,form-data等格式使 ...
- Django框架深入了解_04(DRF之url控制、解析器、响应器、版本控制、分页)(二)
解析器介绍: 所谓解析器,就是前端传过来的数据,后端可以解析,从request.data中取出来,默认的解析器配置是三种编码格式都可以取 回到顶部 解析器的作用: 根据请求头(content-type ...
- Django框架深入了解_04(DRF之url控制、解析器、响应器、版本控制、分页)(一)
阅读目录 一.url控制 基本路由写法:最常用 第二种写法:继承ModelViewSet 第三种写法:(自动生成路由,必须继承ModelViewSet) 二.解析器 前端不同的数据格式请求,后端解析得 ...
- DRF - 解析器组件
DRF之解析器组件 引入 Django RestFramework帮助我们实现了处理application/json协议请求的数据,另外,我们也提到,如果不使用DRF,直接从request.body里 ...
- 详解Spring MVC 4之ViewResolver视图解析器
所有的We MVC框架都有一套它自己的解析视图的机制,Spring MVC也不例外,它使用ViewResolver进行视图解析,让用户在浏览器中渲染模型.ViewResolver是一种开箱即用的技术, ...
- django_rest_framework之解析器、渲染器
一.解析器 DRF中的解析器(类) 1.可以根据请求头中的Content-Type来自动解析参数,使用统一的data属性来获取即可 2.默认3个解析器类JSONParser.FormParser.Mu ...
- Django REST framework 解析器和渲染器
解析器的作用 解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己可以处理的数据.本质就是对请求体中的数据进行解析. 在了解解析器之前,我们要先知道Accept以及ContentType请求 ...
- rest_framework学习之解析器(Parsers)
概述 什么是解析器?在DRF中,解析器是一个类列表,当每次接收到请求时,RDF会根据请求头中的Content-type,来指定使用哪钟解析方法去解析数据.当content-type与解析器列表均不匹配 ...
- java 解析器_高性能Java解析器实现过程详解
如果你没有指定数据或语言标准的或开源的Java解析器, 可能经常要用Java实现你自己的数据或语言解析器.或者,可能有很多解析器可选,但是要么太慢,要么太耗内存,或者没有你需要的特定功能.或者开源解析 ...
最新文章
- 线性八叉树_octree八叉树数据结构原理与实现
- 8个主流且实用的Python开发工具推荐
- Mongodb实现多表join
- 区域转换为二值图像_Matlab图像处理系列教程(一)
- 内核编程之Hello_kernel
- 数字图像处理基础与应用学习,第二章
- Android近场通信---NFC基础(一)
- 神经网络技巧篇之寻找最优超参数
- LayaAir 2.0 开发 2048 小游戏
- mysql-入门教程
- 疯狂java 视频_疯狂Java讲义配书视频教程 下载
- cad小插件文字刷_CAD实用小插件,这是一串让你效率提升相见恨晚的代码!
- Java中除法运算符简介说明
- DevExpress的双击获取单元格数据
- sybase datediff mysql_Sybase中的日期时间函数_龙的天空
- 详解电容触控芯片与指纹芯片的研发与生产流程
- android 设备驱动
- GREE通过改由Rimini Street为其SAP应用提供支持服务来加快推进以业务为驱动力的IT发展路线图
- c语言 1!+2!+···+20!1的阶乘加2的阶乘一直加到20的阶乘
- 地摊金融沦为噱头?贷款需要有房产,“被城管驱逐就赔款”
热门文章
- python全栈-Day 1
- python特殊函数__str__、__repr__和__len__
- POJ1201 区间
- 【leetcode】Combinations (middle)
- java sql 登录失败_java – 接收连接到SQL Server 2008的SQLException“用户登录失败”
- LeetCode-reverse integer复杂度
- python3:(unicode error) 'utf-8' codec can't decode
- python 定时任务系统_Python定时任务,实现自动化的方法
- 万字长文:对账系统从入门到精通(建议收藏)
- 计算机图形标定学,计算机图形学(璩柏青)第10章空间形体的三维重建与图像处理.ppt...