url控制

第二种写法(只要继承了ViewSetMixin)

  1. url(r'^pub/$',views.Pub.as_view({'get':'list','post':'create'})), #获取所有记得路由后面加$结束符 #pub/?format=json
  2. url(r'^pub\.(?P<format>\w+)$',views.Pub.as_view({'get':'list','post':'create'})), #pub.json
  3. url(r'^pub/(?P<pk>\d+)$',views.Pub.as_view({'get':'retrieve','put':'update','delete':'destroy'})), #获取一条

第三种(自动生成路由,必须继承ModelViewSet)

  1. from django.conf.urls import url,include

  SimpleRouter 自动生成两条路由

  1. from rest_framework.routers import SimpleRouter,DefaultRouter #路由控制
  2.  
  3. router = SimpleRouter()
  4. router.register('pub',views.Pub)
  5.  
  6. urlpatterns = [
  7. url(r'^admin/', admin.site.urls),
  8. #其他路由
  9.  
  10. url(r'',include(router.urls)),]

  DefaultRouter自动生成四条路由

  1. from rest_framework.routers import SimpleRouter,DefaultRouter #路由控制
  2.  
  3. router = DefaultRouter()
  4. router.register('pub',views.Pub)
  5.  
  6. urlpatterns = [
  7. url(r'^admin/', admin.site.urls),
  8. #其他路由
  9. url(r'',include(router.urls)),]
解析器(一般不需要动,项目最开始全局配置一下就可以了)

作用:控制视图类能够解析前端传过来的格式是什么样的 (默认配置三种都有) 有application/json,x-www-form-urlencoded,form-data等格式

全局使用:在settings中配置:

  1. REST_FRAMEWORK = {
  2. "DEFAULT_PARSER_CLASSES":[
  3. 'rest_framework.parsers.JSONParser',]
  4. }

局部使用:

  1. from rest_framework.parsers import JSONParser,FormParser,MultiPartParser,FileUploadParser
  2. #json字典 urlencoded form-data 文件

  在视图类中

  1. parser_classes=[JSONParser,]

源码流程

  当调用request.data的时候去执行解析方法

-->根据传过来的编码方式选择一个解析器对象

--->调用解析器对象的parser方法完成解析

  1. 在调用request.data时,才进行解析,由此入手
  2. @property
  3. def data(self):
  4. if not _hasattr(self, '_full_data'):
  5. self._load_data_and_files()
  6. return self._full_data
  7. 查看self._load_data_and_files()方法---->self._data, self._files = self._parse()
  8.  
  9. def _parse(self):
  10. #用户请求头里content_type的值
  11. media_type = self.content_type
  12.  
  13. #self.parsers 就是用户配置的parser_classes = [FileUploadParser,FormParser ]
  14. #self里就有content_type,传入此函数
  15. parser = self.negotiator.select_parser(self, self.parsers)
  16. 查看self.negotiator.select_parser(self, self.parsers)
  17. def select_parser(self, request, parsers):
  18. #同过media_type和request.content_type比较,来返回解析器,然后调用解析器的解析方法
  19. #每个解析器都有media_type = 'multipart/form-data'属性
  20. for parser in parsers:
  21. if media_type_matches(parser.media_type, request.content_type):
  22. return parser
  23. return None
  24. 最终调用parser的解析方法来解析parsed = parser.parse(stream, media_type, self.parser_context)

源码注释

  1. Request实例化,parsers=self.get_parsers()
  2. Request(
  3. request,
  4. parsers=self.get_parsers(),
  5. authenticators=self.get_authenticators(),
  6. negotiator=self.get_content_negotiator(),
  7. parser_context=parser_context
  8. )
  9. get_parsers方法,循环实例化出self.parser_classes中类对象
  10. def get_parsers(self):
  11. return [parser() for parser in self.parser_classes]
  12. self.parser_classes 先从类本身找,找不到去父类找即APIVIew 中的
  13. parser_classes = api_settings.DEFAULT_PARSER_CLASSES
  14. api_settings是一个对象,对象里找DEFAULT_PARSER_CLASSES属性,找不到,会到getattr方法
  15. def __getattr__(self, attr):
  16. if attr not in self.defaults:
  17. raise AttributeError("Invalid API setting: '%s'" % attr)
  18.  
  19. try:
  20. #调用self.user_settings方法,返回一个字典,字典再取attr属性
  21. val = self.user_settings[attr]
  22. except KeyError:
  23. # Fall back to defaults
  24. val = self.defaults[attr]
  25.  
  26. # Coerce import strings into classes
  27. if attr in self.import_strings:
  28. val = perform_import(val, attr)
  29.  
  30. # Cache the result
  31. self._cached_attrs.add(attr)
  32. setattr(self, attr, val)
  33. return val
  34. user_settings方法 ,通过反射去setting配置文件里找REST_FRAMEWORK属性,找不到,返回空字典
  35. @property
  36. def user_settings(self):
  37. if not hasattr(self, '_user_settings'):
  38. self._user_settings = getattr(settings, 'REST_FRAMEWORK', {})
  39. return self._user_settings

源码注释2

响应器

解析成字符串 还是一个浏览器页面

  1. from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer #解析成字符串 还是浏览器样式的
  2. # 不用动,就用全局配置即可默认配置中两个都有

全局使用

  在settings中配置 settings默认配置中两个都有

  1. REST_FRAMEWORK = {
  2. 'DEFAULT_PARSER_CLASSES':[
  3. 'rest_framework.parsers.JSONParser',
  4. ],
  5. # 响应器 默认配置两个都由 这个是全局使用
  6. # 'DEFAULT_PARSER_CLASSES':[ 'rest_framework.renderers.JSONRenderer',
  7. # 'rest_framework.renderers.BrowsableAPIRenderer',]
  8.  
  9. }

局部使用

  在试图类中配置

  1. renderer_classes = [JSONRenderer, BrowsableAPIRenderer]
版本控制

作用用于控制版本    视图中 版本问题需要接受版本传过来的参数 注意是单个没有复数

内置版本控制

  1. from rest_framework.versioning import QueryParameterVersioning,AcceptHeaderVersioning,NamespaceVersioning,URLPathVersioning
  2.  
  3. #基于url的get传参方式:QueryParameterVersioning------>如:/users?version=v1
  4. #基于url的正则方式:URLPathVersioning------>/v1/users/
  5. #基于 accept 请求头方式:AcceptHeaderVersioning------>Accept: application/json; version=1.0
  6. #基于主机名方法:HostNameVersioning------>v1.example.com
  7. #基于django路由系统的namespace:NamespaceVersioning------>example.com/v1/users/

局部使用

  1. #在CBV类中加入
  2. versioning_class = URLPathVersioning
  1. url中需要写
  1. url(r'(?P<version>[v1|v2])/register/$',views.Register.as_view()),
  2. url(r'(?P<version>[v1|v2])/register\.(?P<format>\w+)$',views.Register.as_view()),
  3. url(r'(?P<version>[v1|v2])/register/(?P<pk>\d+)$',views.Register.as_view()),

写访问路由的的时候要写上版本

  1.  

全局使用

  在settings中配置

  1. REST_FRAMEWORK = {
  2. "DEFAULT_PARSER_CLASSES":[
  3. 'rest_framework.parsers.JSONParser',
  4. ],
  5. 'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning',
  6. 'DEFAULT_VERSION': 'v1', # 默认版本(从request对象里取不到,显示的默认值)
  7. 'ALLOWED_VERSIONS': ['v1', 'v2'], # 允许的版本
  8. 'VERSION_PARAM': 'version', # URL中获取值的key
  9.  
  10. }

路由不要写

  1. url(r'register/$',views.Register.as_view()),

但是访问路由的时候需要写上版本

在试图类中就可以通过,request.vesrsion取出当前访问哪个版本,相应的去执行相应版本的代码

示例

基于正则的方式

  1. from django.conf.urls import url, include
  2. from web.views import TestView
  3.  
  4. urlpatterns = [
  5. url(r'^(?P<version>[v1|v2]+)/test/', TestView.as_view(), name='test'),
  6. ]
  7.  
  8. url
  1. from rest_framework.views import APIView
  2. from rest_framework.response import Response
  3. from rest_framework.versioning import URLPathVersioning
  4.  
  5. class TestView(APIView):
  6. versioning_class = URLPathVersioning
  7.  
  8. def get(self, request, *args, **kwargs):
  9. # 获取版本
  10. print(request.version)
  11. # 获取版本管理的类
  12. print(request.versioning_scheme)
  13.  
  14. # 反向生成URL
  15. reverse_url = request.versioning_scheme.reverse('test', request=request)
  16. print(reverse_url)
  17.  
  18. return Response('GET请求,响应内容')
  19.  
  20. views.py

View.py

  1. # 基于django内置,反向生成url
  2. from django.urls import reverse
  3. url2=reverse(viewname='ttt',kwargs={'version':'v2'})
  4. print(url2)

源码分析

  1. #执行determine_version,返回两个值,放到request对象里
  2. version, scheme = self.determine_version(request, *args, **kwargs)
  3. request.version, request.versioning_scheme = version, scheme
  4.  
  5. def determine_version(self, request, *args, **kwargs):
  6. #当配置上版本类之后,就会实例化
  7. if self.versioning_class is None:
  8. return (None, None)
  9. scheme = self.versioning_class()
  10. return (scheme.determine_version(request, *args, **kwargs), scheme)
分页

 常规分页   查看第n页 每页显示多少条

  1. #分页 #常规分页 偏移分页 cursor游标分页
  2. from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination
  3.  
  4. class PublishView(APIView):
  5. versioning_class = URLPathVersioning
  6. parser_classes = [JSONRenderer,] #解析器
  7.  
  8. def get(self,request,*args,**kwargs):
  9. #第一种方法,普通分页
  10. '''
  11. 查询出所有数据
  12. 实例化产生一个普通分页对象
  13. 每页显示多少条
  14. 查询指定查询那一页的key值
  15. '''
  16. ret= models.Publish.objects.all()
  17. page = PageNumberPagination()
  18. page.page_size = 3 #每页显示多少条
  19. page.page_query_param = 'page' #按照page名词显示那一页
  20.  
  21. # 前端控制每页显示多少条的查看key值必然要size=9,表示一页显示9条
  22. page.page_size_query_param = 'size'
  23. #控制每页最大显示多少,size如果传100,最多也是显示10
  24. page.max_page_size = 10
  25. ret_page = page.paginate_queryset(ret,request,self)
  26. #序列化
  27. pub_ser = PublishSerlizers(ret_page,many=True)
  28. #去settings中配置每页显示多少条 这个是全局配置的话 局部配置全局可以不配置
  29.  
  30. return Response(pub_ser.data)

settings中配置

  1. REST_FRAMEWORK = {
  2. # 每页显示两条
  3. 'PAGE_SIZE':2
  4. }

路由

  1. url(r'^(?P<version>[v1|v2]+)/publish/',views.PublishView.as_view())

serializer

  1. from rest_framework.serializers import ModelSerializer
  2. from app01 import models
  3. class PublishSerlizers(ModelSerializer):
  4. class Meta:
  5. model = models.Publish
  6. fields = '__all__'

偏移分页   在第n个位置向前向后查询第n个位置

  1. #分页 #常规分页 偏移分页 cursor游标分页
  2. from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination
  3.  
  4. class PublishView(APIView):
  5. versioning_class = URLPathVersioning
  6. parser_classes = [JSONRenderer,] #解析器
  7.  
  8. def get(self,request,*args,**kwargs): #偏移分页
  9. ret = models.Publish.objects.all()
  10. #实例化产生一个偏移分页对象
  11. page= LimitOffsetPagination()
  12. # 四个参数:
  13. # 从标杆位置往后取几个,默认取3个,可以指定
  14. page.default_limit = 3
  15. # 每条取得条数
  16. page.limit_query_param ='limit'
  17. # 标杆值,现象偏移到那个位置,如果offset=6, 表示当前在第6条位置上,往后取
  18. page.offset_query_param = 'offset'
  19. # 最大取10条
  20. page.max_limit = 10
  21.  
  22. ret_page = page.paginate_queryset(ret,request,self)
  23. #序列化
  24. pub_ser= PublishSerlizers(ret_page,many=True)
  25. #取settings中配置每页显示多少条
  26. return page.get_paginated_response(pub_ser.data)

 cursor游标分页

  1. from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination
  2. class PublishView(APIView):
  3. versioning_class = URLPathVersioning
  4. parser_classes=[JSONParser,]
  5.  
  6. def get(self, request, *args, **kwargs):
  7. ret = models.Publish.objects.all()
  8. # 实例化产生一个偏移分页对象
  9. page = CursorPagination()
  10. #三个参数:
  11. #每页显示的大小
  12. page.page_size=3
  13. #查询的key值
  14. page.cursor_query_param='cursor'
  15. # 按什么排序
  16. page.ordering='id'
  17.  
  18. ret_page = page.paginate_queryset(ret, request, self)
  19. # 序列化
  20. pub_ser = serializer.PublishSerializers(ret_page, many=True)
  21. # 去setting中配置每页显示多少条
  22. return page.get_paginated_response(pub_ser.data)

DRF url控制 解析器 响应器 版本控制 分页(常规分页,偏移分页,cursor游标分页)的更多相关文章

  1. drf 解析器,响应器,路由控制

    解析器 作用: 根据请求头 content-type 选择对应的解析器对请求体内容进行处理. 有application/json,x-www-form-urlencoded,form-data等格式 ...

  2. Django框架深入了解_04(DRF之url控制、解析器、响应器、版本控制、分页)

    一.url控制 基本路由写法:最常用 from django.conf.urls import url from django.contrib import admin from app01 impo ...

  3. DRF的解析器和渲染器

    解析器 解析器的作用 解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己可以处理的数据.本质就是对请求体中的数据进行解析. 在了解解析器之前,我们要先知道Accept以及ContentTy ...

  4. DRF 的解析器和渲染器

    一.解析器 解析器作用 解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己可以处理的数据.本质就是对请求体中的数据进行解析. 在了解解析器之前,我们要先知道Accept以及ContentT ...

  5. 【DRF解析器和渲染器】

    目录 解析器 Django中的解析器 DRF中的解析器 DRF中的渲染器 @ *** 解析器 解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己想要的数据类型的过程. 本质就是对请求体中的 ...

  6.  Django REST framework解析器和渲染器

    解析器 解析器的作用 解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己可以处理的数据.本质就是对请求体中的数据进行解析. 在了解解析器之前,我们要先知道Accept以及ContentTy ...

  7. 打造属于前端的Uri解析器

    今天和大家一起讨论一下如何打造一个属于前端的url参数解析器.如果你是一个Web开发工程师,如果你了解过后端开发语言,譬如:PHP,Java等,那么你对下面的代码应该不会陌生: $kw = $_GET ...

  8. 高性能Java解析器实现过程详解

    如果你没有指定数据或语言标准的或开源的Java解析器, 可能经常要用Java实现你自己的数据或语言解析器.或者,可能有很多解析器可选,但是要么太慢,要么太耗内存,或者没有你需要的特定功能.或者开源解析 ...

  9. Django REST framework基础:解析器和渲染器

    解析器 解析器的作用 解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己可以处理的数据.本质就是对请求体中的数据进行解析. 在了解解析器之前,我们要先知道Accept以及ContentTy ...

随机推荐

  1. csp-s模拟84

    T1: 考虑如何能按顺序生成光滑数.对每个质数用队列维护包含此质数的候选集合,每次从所有队首取出最小的作为一个光滑数,用每个质数乘上这个光滑数并加入相应候选集合.这样不会漏掉一个光滑数,但会有重复.比 ...

  2. python 二进制加法

    bin(int(a,2)+int(b,2))[2:]

  3. app支付宝充值

    首先支付宝需要开通app 支付 然后登录支付宝 ,点击合作伙伴, 进入 开放平台,申请一个应用. 下载支付宝开放平台助手, 生成应用公钥,点击上传 设置进入之前申请的应用,支付宝自动生成支付宝公钥,设 ...

  4. 手把手教你在Linux系统下安装MongoDB

    1. 下载最新的stable版MongoDB [root@spirit-of-fire ~]# wget http://downloads.mongodb.org/linux/mongodb-linu ...

  5. 整合spring boot时操作数据库时报错Caused by: java.lang.InstantiationException: tk.mybatis.mapper.provider.base.B

    原文:https://blog.csdn.net/u__f_o/article/details/82756701 一般出现这种情况,应该是没有扫描到对应的mapper包,即在启动类下配置MapperS ...

  6. map,实现技巧,id

    cf #include<iostream> #include<cstdio> #include<algorithm> #include<vector> ...

  7. php屏蔽电话号码中间四位

    php屏蔽电话号码中间四位 一.总结 一句话总结: 直接就是substr_replace函数:$str = substr_replace("13966778888",'****', ...

  8. [log4j]Error:The method getLogger(String) in the type Logger is not applicable for the arguments

    原因:本该导入import org.apache.log4j.Logger; 结果成了import java.util.logging.Logger; 如果硬把private static Logge ...

  9. JVM | JVM的核心技术

    说到JVM,很多工作多年的老铁,可能就有点发憷了,因为搬砖多年,一直使用java这个工具,对于JVM没有了解过,有句话面试造航母,上班拧螺丝,要啥自行车啊,知道如何搬砖就可以了,为啥要懂这么多,如果你 ...

  10. openstack核心组件--cinder存储服务(6)

    一.cinder 介绍:   理解 Block Storage 操作系统获得存储空间的方式一般有两种: 通过某种协议(SAS,SCSI,SAN,iSCSI 等)挂接裸硬盘,然后分区.格式化.创建文件系 ...