04-Django REST framwork 板块(04-版本、05-解析器)

本文深入探讨了Django REST framework中版本控制的两种方式:URL路径和GET参数,并详细介绍了如何配置版本控制及解析器。通过实例展示了如何在URL中传参以实现版本控制,以及如何配置解析器以自动解析请求体数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Django REST framework 板块

4. 版本

  • 共三个值需要设置(见源码):
    • 1.self.version_param 传输版本的键('version’还是’V’等)
    • 2.self.default_version 默认版本
    • 3.self.is_allow_version 允许的版本

a. URL中通过GET传参()

  • 自定义的写法:
	http://127.0.0.1:8000/api/users/?version=v2
	from rest_framework.versioning import QueryParameterVersioning
	
	class ParamVersion(object):
		def determine_version(self, request, *args, **kwargs):
			# query_params等同于._request.GET   
			version = request.query_params.get('version')
			return version

	class UsersView(APIView):

		versioning_class = ParamVersion
		def get(self,request,*args,**kwargs):
			#version = request._request.GET.get('version')
			#print(version)
			# version = request.query_params.get('version')
			# print(version)

			print(request.version)

			return HttpResponse('用户列表')

b. 在URL中传参(推荐使用)

	from rest_framework.versioning import URLPathVersioning
	
	urlpatterns = [
		# url(r'^admin/', admin.site.urls),
		url(r'^(?P<version>[v1|v2]+)/users/$', views.UsersView.as_view()),
	]

	
	REST_FRAMEWORK = {
		"DEFAULT_VERSIONING_CLASS":"rest_framework.versioning.URLPathVersioning",
		"DEFAULT_VERSION":'v1',
		"ALLOWED_VERSIONS":['v1','v2'],
		"VERSION_PARAM":'version',
	}
	
	class UsersView(APIView):

		def get(self,request,*args,**kwargs):
			print(request.version)
			return HttpResponse('用户列表')
总结使用
  • 直接配置配置文件(基本不变化):
    REST_FRAMEWORK = {
    	"DEFAULT_VERSIONING_CLASS":"rest_framework.versioning.URLPathVersioning",
    	"DEFAULT_VERSION":'v1',
    	"ALLOWED_VERSIONS":['v1','v2'],
    	"VERSION_PARAM":'version',
    } 
  • 路由系统:
	urlpatterns = [
		# url(r'^admin/', admin.site.urls),
		url(r'^api/', include('api.urls')),
	]

	urlpatterns = [
		# url(r'^admin/', admin.site.urls),
		url(r'^(?P<version>[v1|v2]+)/users/$', views.UsersView.as_view(),name='uuu'),
	]
  • 视图:
	class UsersView(APIView):

	def get(self,request,*args,**kwargs):

		# 1. 获取版本
		print(request.version)
		
		# 2. 获取处理版本的对象
		print(request.versioning_scheme)

		# 3. 根据对象反向生成URL(rest framework对Django的在封装)
		u1 = request.versioning_scheme.reverse(viewname='uuu',request=request)
		print(u1)

		# 4. 反向生成URL(利用Django自己定义的方式)
		u2 = reverse(viewname='uuu',kwargs={'version':2})
		print(u2)

		return HttpResponse('用户列表')

5. 解析器

前戏:django:request.POST/ request.body

请求头要求:
Content-Type: application/x-www-form-urlencoded
> PS:
如果请求头中为 Content-Type: "application/x-www-form-urlencoded",request.POST中才有值(去request.body中解析数据,放到post中,才实现post中有值)。
如果请求头中的 Content-Type: "application/json; charset=utf-8" 那么只有在request.body中才有值

数据格式要求:
name=alex&age=18&gender=男

如:form 和 ajax的默认请求数据格式,都是form形式,要使用json传输,需要如下进行设置。

  • a. form表单提交
		<form method...>
			input...	
		</form>
  • b.ajax提交
		$.ajax({
			url:...
			type:POST,
			data:{name:alex,age=18}       // 内部转化 name=alex&age=18&gender=男
		})
	
	// body有值;POST有值
  • 情况一:
		$.ajax({
			type:"POST",
			url:"http://127.0.0.1:8000/api/v1/users/",
			contentType:"application/json; charset=utf-8",
			data:{"name":"alex"}  // 内部转化为name=alex
		});
		// body有值;POST无 
  • 情况二:
		$.ajax({
			type:"POST",
			url:"http://127.0.0.1:8000/api/v1/users/",
			contentType:"application/json; charset=utf-8",
			data:JSON.stringify({"name":"alex"})   // 传过去的是json字符串
		});
		// body有值;POST无
		// 使用json.loads(request.body)将得到的json字符串序列化为字典

rest_framework 的解析器,对请求体数据进行解析。JSONParser专门对json数据进行解析

总结使用

  • 配置:(配置好后,会自动解析,只需要request.data或者request.files等去拿数据就行;不止下边两种解析器,其他见源码)
REST_FRAMEWORK = {
	"DEFAULT_PARSER_CLASSES":['rest_framework.parsers.JSONParser','rest_framework.parsers.FormParser']
}
  • 视图:
from rest_framework.parsers import JSONParser

class ParserView(APIView):
# parser_classes = [JSONParser,FormParser,]   # 使用的解析器类型,可在settings直接配置全局
"""
JSONParser:表示只能解析content-type:application/json头  (用的最多,后边可加charset=utf-8避免字符编码的问题)
FormParser:表示只能解析content-type:application/x-www-form-urlencoded头
"""

def post(self,request,*args,**kwargs):
	"""
	允许用户发送JSON格式数据
		a. content-type: application/json
		b. {'name':'alex',age:18}
	"""
	"""
	程序处理流程:
		1. 获取用户请求
		2. 获取用户请求体body
		3. 根据用户请求头 和 parser_classes = [JSONParser,FormParser,] 中支持的请求头进行比较
		4. JSONParser对象去请求体解析数据
		5. 处理后,赋值给request.data    
	"""
	"""
		当发送过来的数据为如下json时:
			{
				"name":"alex",
				"age":13
			}
		在post接收到数据后得到的结果如下:
			print(type(request._request))   # <class 'django.core.handlers.wsgi.WSGIRequest'>
			print('body:',request.body)		# body: b'{\n\t"name":"alex",\n\t"age":13\n}'
			print('post:',request._request.POST.get('name'))  # post: None
			import json
			body = json.loads(request.body)
			print(type(body))  # <class 'dict'>
			print(body)  # {'name': 'alex', 'age': 13}
			print(body['name'])  # alex
	"""
	print(request.data)


	return HttpResponse('ParserView')

其他解析器:(具体操作见源码/博客)
JSONParser/FormParser/MultiPartParser/FileUploadParser
(后两者相似,都可以上传文件。在request.body中,前边是既有数据又有文件,后边只能是文件)

  • 源码流程 & 本质:(总结下)
    • a. 本质(根据请求头的content-type类型来)
      请求头 :…
      状态码: …
      请求方法:…
    • b. 源码流程
      • dispatch: request封装
      • request.data

自己的理解:
- 解析器是针对客户端请求request的数据,进行的解析或者序列化
- 序列化是针对查到的数据库的queryset类型进行序列化,要对得到的数据,进行每个字段进行序列化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值