5 解析器、url路由控制、分页、渲染器和版本
1 数据解析器
1 什么是解析器
相当于request 中content-type
对方传什么类型的数据,我接受什么样的数据;怎样解析
无论前面传的是什么数据,都可以解开
例如:django不能解析json数据,restfrmaework可以解析
django只能解开,urlcode的数据
添加一本书籍,传json数据
2 5种解析器
j
支持4个
解析二进制文件用
常用的2个解析器
默认使用3个
3 JSONParser解析器
反序列化 json--dict
如何引用,
走我的,只能解析一种JSON
test
现在只能解析1 中 json
4 FormParser解析器
添加form解析器
5 Code与笔记
笔记
7 解析器-----数据解析器 from rest_framework.parsers import JSONParser,FormParser,MultiPartParser,FileUploadParser parser_classes = [JSONParser,FormParser]
view
from rest_framework.parsers import JSONParser from rest_framework.parsers import FormParser class BookView(APIView): # authentication_classes = [TokenAuth,] # 认证组件 # permission_classes =[] # 权限组件 # throttle_classes = [] # 频率组件 # parser_classes = [JSONParser] parser_classes = [JSONParser,FormParser] def get(self,request): book_list = Book.objects.all() bs = BookModelSerializers(book_list,many=True,context={'request':request}) return Response(bs.data) # Response继承HttpResponse def post(self,request): # post请求的数据 print(request.data) # self.dispatch bs = BookModelSerializers(data=request.data,context={'request':request}) if bs.is_valid(): print(bs.validated_data) bs.save() # create方法 return Response(bs.data) else: return Response(bs.errors)
2 url控制
1.针对 视图3 viewset
最后一种方式,有4条url
4条url
url 有重复的内容,如何优化
2.官方文档
注册下
自动生成url的路径
3. 如何生成4条url
这4条是帮我生成的
test
4.code
路由控制 针对: url(r'^authors/$', views.AuthorModelView.as_view({"get":"list","post":"create"}),name="author"), url(r'^authors/(?P<pk>\d+)/$', views.AuthorModelView.as_view({"get":"retrieve","put":"update","delete":"destroy"}),name="detailauthor"), class AuthorModelView(viewsets.ModelViewSet): queryset = Author.objects.all() serializer_class = AuthorModelSerializers
url 配置
from rest_framework import routers routers = routers.DefaultRouter() routers.register('authors',views.AuthorView) urlpatterns = [
... re_path('^',include(routers.urls)),
... ]
3 分页器
django有分页
rest 也有分页
1.简单分页
(1)源码
page_size 每页显示多少条数据 page_query_param 分页结果集中的页码 page_size_query_param 每页返回的结果数 max_page_size 将其设置为整数,以限制客户机可能请求的最大页面大小 Only relevant if 'page_size_query_param' has also been set
(2)全局配置
test
(3)局部配置
每页显示2个 参数 page page=1 &size = 3 第一页默认2条,临时改成3条 最大不能超过3个,限制临时size
先分页,分完后,进行序列化
2.偏移分页(不常用)
(1) 源码
default_limit
limit_query_param 每页返回的结果数。
offset_query_param 返回结果的初始索引
(2)自定义
默认显示1
(3)test
在此基础后,偏移1
拿到第二个,类似于 相对路径
3.视图3 Viewset:一句话分页
(1)对于视图modelviewset,如何分页?
只需要加1个即可,源码里面有分页
谁的self.paginate_queryset(queryset)
找pagination_class即可
(2)以后,3句话就完成分页了
(3)test
4.代码
views
from rest_framework.pagination import PageNumberPagination # 简单分页 from rest_framework.pagination import LimitOffsetPagination # 偏移分页 class MyPageNumberPagination(PageNumberPagination): page_size = 1 page_query_param = 'page' page_size_query_param = 'size' max_page_size = 3 class MyLimitOffsetPagination(LimitOffsetPagination): default_limit = 1 class BookView(APIView): def get(self,request): book_list = Book.objects.all() # 分页 pnp = MyPageNumberPagination() # pnp = LimitOffsetPagination() book_age = pnp.paginate_queryset(book_list,request,self) bs = BookModelSerializers(book_age,many=True,context={'request':request}) return Response(bs.data) # Response继承HttpResponse def post(self,request): # post请求的数据 print(request.data) # self.dispatch bs = BookModelSerializers(data=request.data,context={'request':request}) if bs.is_valid(): print(bs.validated_data) bs.save() # create方法 return Response(bs.data) else: return Response(bs.errors) # Author # 视图三部曲,最后一种 from rest_framework import viewsets class AuthorView(viewsets.ModelViewSet): queryset = Author.objects.all() serializer_class = AuthorModelSerializers pagination_class = MyPageNumberPagination
settings
REST_FRAMEWORK = { # Pagination 'PAGE_SIZE': 1, }
4 Response响应器
1.之前提到的
https://www.cnblogs.com/venicid/p/11231983.html#_label3_1
2、源码
Response 只是一堆数据
HTTPResponse 只能放字符串
用浏览器的话,默认是用户,给个html页面
方便用户操作
后续可以delete请求,只有json数据的话,没有
实质还是请求的还是数据
实质:json数据
5 渲染器
1.demo
主urls
from django.contrib import admin from django.urls import path,re_path,include urlpatterns = [ path('admin/', admin.site.urls), path('api/',include('api.urls')) ]
api.urls
from django.urls import path,re_path,include from api.views import course urlpatterns = [ re_path('^course',course.CourseViews.as_view()) ]
view
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer from django.shortcuts import HttpResponse class CourseViews(APIView): # renderer_classes = [JSONRenderer,BrowsableAPIRenderer] renderer_classes = [JSONRenderer] def get(self,request,*args,**kwargs): self.dispatch # 快速找dispatch return Response('course...') # 出错了,没有在app中注册 rest_framework # return HttpResponse('course...')
settings
INSTALLED_APPS = [ ... 'rest_framework', ] ... REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': ['rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.BrowsableAPIRenderer'], }
2.rest_framework如何渲染的
3. 渲染器 JSONRenderer和BrowsableAPIRenderer
一般情况用json即可
restframe实质:把你的json数据嵌套到html中显示
4.全局配置
源码
我的settings设置
6 版本 /api/v1/
1.源码剖析
5种支持的版本传参
继承BaseVersioning
5个类,2个不用
参数配置
2.方法1(不推荐)
(1)源码
实质:django中request的get方法
version参数,与默认
只能指定 v1 v2
(2)局部配置
urls
(3)全局配置
(4)test
不同verison 能拿到不同的版本
没有允许的版本
默认的
3.方法2 URLPathVersioning (推荐版本)
(1)局部配置
version会传到kwargs
(2)全局配置过(推荐版本)
url
(3)test
4. Code和笔记
1、笔记
2. 版本 原理:要了解 使用: 1. 添加配置 REST_FRAMEWORK = { .... 'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning', 'ALLOWED_VERSIONS':['v1','v2'], # 允许的版本 'VERSION_PARAM':'version', # 参数 'DEFAULT_VERSION':'v1', # 默认版本 .... } 2. 设置路由 s9luffycity/urls.py urlpatterns = [ #url(r'^admin/', admin.site.urls), url(r'^api/(?P<version>\w+)/', include('api.urls')), ] api/urls.py urlpatterns = [ url(r'^course/$', course.CourseView.as_view()), ] 3. 获取版本 request.version 获取版本
2、代码
主url
from django.contrib import admin from django.urls import path,re_path,include urlpatterns = [ path('admin/', admin.site.urls), # re_path('api/(?P<version>[v1|v2]+)/',include('api.urls')), re_path('api/(?P<version>\w+)/',include('api.urls')) ]
api.url
from django.urls import path,re_path,include from api.views import course urlpatterns = [ re_path('^course',course.CourseViews.as_view()) ]
api.views.course
from django.shortcuts import HttpResponse from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer from rest_framework.versioning import QueryParameterVersioning from rest_framework.versioning import URLPathVersioning class CourseViews(APIView): # versioning_class = QueryParameterVersioning # versioning_class = URLPathVersioning # 推荐版本 # renderer_classes = [JSONRenderer] # 一般情况使用json即可 # renderer_classes = [JSONRenderer,BrowsableAPIRenderer] def get(self,request,*args,**kwargs): # version会传到kwargs # self.dispatch # 快速找dispatch print(request.version) return Response('course...') # 出错了,没有在app中注册 rest_framework # return HttpResponse('course...')
settings
REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': ['rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.BrowsableAPIRenderer'], # Versioning 'DEFAULT_VERSION': 'v1', # 默认的版本 'ALLOWED_VERSIONS': ['v1','v2'], # 允许的版本 'VERSION_PARAM': 'version', # 参数 # 方式1 # from rest_framework.versioning import QueryParameterVersioning 'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.QueryParameterVersioning', # 方式2:推荐 # from rest_framework.versioning import URLPathVersioning # 'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning', }