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类型进行序列化,要对得到的数据,进行每个字段进行序列化