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

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類型進行序列化,要對得到的數據,進行每個字段進行序列化

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章