深入解析当下大热的前后端分离组件django-rest_framework系列四

匆匆过客 提交于 2020-05-08 03:45:21

查漏补缺系列

解析器

request类

django的request类和rest-framework的request类的源码解析

局部视图

复制代码
复制代码
from rest_framework.parsers import JSONParser,FormParser
class PublishViewSet(generics.ListCreateAPIView): parser_classes = [FormParser,JSONParser] queryset = Publish.objects.all() serializer_class = PublshSerializers def post(self, request, *args, **kwargs): print("request.data",request.data) return self.create(request, *args, **kwargs)
复制代码
复制代码

全局视图

复制代码
复制代码
REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",], "DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",], "DEFAULT_THROTTLE_CLASSES":["app01.service.throttles.VisitThrottle",], "DEFAULT_THROTTLE_RATES":{ "visit_rate":"5/m", }, "DEFAULT_PARSER_CLASSES":['rest_framework.parsers.FormParser',] }
复制代码
复制代码

备注:局部使用指定解析器时,只需在视图类中添加一个变量:parser_classes = [...]

rest_framework全局默认使用的解析器:

复制代码
DEFAULTS = {
    # Base API policies

    'DEFAULT_PARSER_CLASSES': ( 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser', 'rest_framework.parsers.MultiPartParser' ),
复制代码

 

 

分页

简单分页

复制代码
复制代码
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination

class PNPagination(PageNumberPagination): page_size = 1 # 每页显示的数据个数 page_query_param = 'page' #翻页的参数 ?page=num page_size_query_param = "size" #每页临时显示的数据个数 覆盖page_size max_page_size = 5 #每页允许显示的最大条数 class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializers def list(self,request,*args,**kwargs):      # 单写某个视图时的用法 book_list=Book.objects.all() pp=LimitOffsetPagination() pager_books=pp.paginate_queryset(queryset=book_list,request=request,view=self) print(pager_books) bs=BookSerializers(pager_books,many=True) #return Response(bs.data) return pp.get_paginated_response(bs.data)
复制代码
复制代码

偏移分页

from rest_framework.pagination import LimitOffsetPagination

分页器在视图类中的用法:在视图类中定义一个变量: pagination_class=类

 备注:使用LimitOffsetPagination偏移分页,里面的两个参数limit和offset:limit是每页显示的条数,offset是从第几条数据+1开始(offset=3,意为从第四条数据开始)。default_limit = num,默认显示的条数。

游标分页

复制代码
from rest_framework.views import APIView
from .models import UserInfo from rest_framework.response import Response from rest_framework import serializers from rest_framework.pagination import CursorPagination class MyPagination(CursorPagination): # URL传入的游标参数 cursor_query_param = 'cursor' # 默认每页显示的数据条数 page_size = 2 # URL传入的每页显示条数的参数 page_size_query_param = 'page_size' # 每页显示数据最大条数 max_page_size = 1000 # 根据ID从大到小排列 ordering = "id" class PagerSerialize(serializers.ModelSerializer): '''数据序列化''' class Meta: model = UserInfo fields = "__all__" depth = 2 #用于显示关联字段的对应的表的详细内容 class PagerView(APIView): def get(self,request,*args,**kwargs): user_list=UserInfo.objects.all().order_by('-id') #将数据按照id从大到小排序 #根据url参数,获取分页数据 obj=MyPagination() page_user_list=obj.paginate_queryset(user_list,request,self) #数据进行序列化 ser=PagerSerialize(instance=page_user_list,many=True) response=obj.get_paginated_response(ser.data) #返回带上下页连接的数据 return response # return Response(ser.data) #不含上下页链接
复制代码

游标方式分页的本质是通过记住当前页面数据的最大、最小id,翻页时根据记录的最大或者最小id,查询下一页对应的数据,这样就不会出现每一次翻页都会重头遍历数据的情况,大大的提高了查询效率。缺点是无法直接跳转到某一页。

url路由器

我们在使用rest_framework时,url都是一个规定的格式,当我们有很多表时,意味着大量的复用一些代码,对于每一个模型表对应的url,只有两个地方不同,一个是路径的前缀,一个是对应的视图类。在rest_framework中也提供了一个url的分发,完美的解决了url的分发。

from rest_framework import routers

rest_framework提供一个routers的py文件,这个文件中包含跟路由相关的类。

使用方式:在routers.py中有一个DefaultRouter类,先实例化一个这个类的对象,router=routers.DefaultRouter(),通过这个router对象,可以将对应的路径和视图类注册:router.register(r"路径前缀",对应的视图类),最后只需将url(r'^', include(router.urls)),这个url加入到urlpatterns中即可。

备注:rest_framework中为我们提供了四种形式的访问方式:

  1. books/
  2. books/1/
  3. books.json/
  4. books/?format=json            后两种不常用

响应器

rest_framework默认提供给我们两种响应器:

复制代码
DEFAULTS = {
    # Base API policies
    'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.BrowsableAPIRenderer', ),
复制代码

如果请求是浏览器,就用BrowsableAPIRenderer响应器返回一个页面,如果请求是非浏览器(比如Postman),就使用JSONRenderer响应一个json格式的数据。rest_framework提供这两个响应器是为了利于开发。

  我们可以在视图类中配置一个变量:renderer_classes = [JSONRenderer]

from rest_framework.renderers import JSONRenderer

这样我们再使用浏览器发送请求是,响应的是一个json格式的字符串,而不是一个界面。

版本控制

  版本控制是由传入的客户端请求决定的,并且可能基于请求URL,或者基于请求头。

  restframework也提供了对应的版本控制。当使用版本控制时,request.version属性(字符串)与客户端请求的版本一致。 默认情况下,没有使用版本控制,request.version将会返回None,我们可以通过request.version的值进行判断和逻辑分发.

基于请求url:

复制代码
class APIView(View):
    # 版本控制的默认配置    可以在局部中定义versoning_class=的自定义配置
    versioning_class = api_settings.DEFAULT_VERSIONING_CLASS def initial(self, request, *args, **kwargs): # 版本控制相关 # Determine the API version, if versioning is in use. version, scheme = self.determine_version(request, *args, **kwargs) request.version, request.versioning_scheme = version, scheme 
复制代码

 

版本配置

全局配置

1. 添加配置
1
2
3
4
5
6
7
8
9
10
REST_FRAMEWORK = {
              
              ....
              
              'DEFAULT_VERSIONING_CLASS' : 'rest_framework.versioning.URLPathVersioning' ,
              'ALLOWED_VERSIONS' :[ 'v1' , 'v2' ], # 允许的版本
              'VERSION_PARAM' : 'version' , # 参数
              'DEFAULT_VERSION' : 'v1' , # 默认版本
              ....
       }
2. 设置路由
1
2
3
4
5
6
7
8
9
10
BeesCity / 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. 传递版本信息
1
http: / / 127.0 . 0.1 : 8000 / api / v1 / course /
4. 获取版本
1
request.version 获取版本 

 

局部配置

除非明确设置,否则DEFAULT_VERSIONING_CLASS值为None.此例中request.version将会始终返回None 
您还可以在一个单独的视图上设置版本控制方案。通常,您不需要这样做,因为在全局范围内使用一个版本控制方案更有意义。如果您确实需要这样做,请使用versioning_class属性。

1
2
3
4
from rest_framework.versioning import QueryParameterVersioning
 
class Course(APIView):
     versioning_class = QueryParameterVersioning

  这个时候可以用过url传参的方式来传递版本信息,如:

 

1
http: / / 127.0 . 0.1 : 8000 / api / course / ?version = 1

 

添加头信息控制版本

在API请求header中添加Accept字段。
Accept的作用是客户端指出响应可以接受的媒体类型
如Accept:application/json; version=v2
具体格式也可以参考下面。

Accept: application/vnd.xxxx[.version].param[+json]

例如Accept: application/vnd.demo.app-v2+json

  总结:小版本的更新可通过把版本号作为参数的方式或者通过accept字段标示版本号的方式判断,大的版本更新则通过URL上添加版本号控制

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!