Django REST framework 板塊
4. 版本
- 共三個值需要設置(見源碼):
- 1.
self.version_param
傳輸版本的鍵('version’還是’V’等) - 2.
self.default_version
默認版本 - 3.
self.is_allow_version
允許的版本
- 1.
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
- a. 本質(根據請求頭的content-type類型來)
自己的理解:
- 解析器是針對客戶端請求request的數據,進行的解析或者序列化
- 序列化是針對查到的數據庫的queryset類型進行序列化,要對得到的數據,進行每個字段進行序列化