一、版本
版本控制:当程序越来越大,后期需要再加入一些功能或者进行二次开发时就需要加上版本号了。
之前我们在没有接触rest_framework之前一般是以下这种方式来实现的
class UserView(APIView): def get(self,request,*args,**kwargs): version = request.query_params.get('version') print(version) if version=='v1': #如果版本是v1 ret = { 'code':111, 'msg':'版本一的内容' } elif version=='v2': # 如果是v2 ret = { 'code': 112, 'msg': '版本二的内容' } else: ret = { 'code': 0, 'msg': '不支持其他版本' } return Response(ret)
现在我们可以用rest_framework来实现,主要有两种方式
方式一:基于url
#基于url传参的形式 versioning_class = QueryParameterVersioning #http://127.0.0.1:8080/api/users/?version=v2 #基于url的形式 versioning_class = URLPathVersioning #http://127.0.0.1:8080/api/v1/users/
具体操作

REST_FRAMEWORK = { 'DEFAULT_VERSION': 'v1', #默认的版本 'ALLOWED_VERSIONS': ['v1','v2'], #允许的版本 'VERSION_PARAM': 'version', }

1 from django.conf.urls import url,include 2 from django.contrib import admin 3 4 5 urlpatterns = [ 6 url(r'^admin/', admin.site.urls), 7 url(r'^api/(?P<version>[v1|v2]+)/', include('api.urls'), name='users-list'), 8 ]

1 from api import views 2 urlpatterns = [ 3 # url(r'^users/', views.UserView.as_view()), 4 url(r'^users/', views.UserView1.as_view()), 5 6 ]

class UserView1(APIView): #基于url传参的形式 # versioning_class = QueryParameterVersioning #http://127.0.0.1:8080/api/users/?version=v2 #基于url的形式 #http://127.0.0.1:8080/api/v1/users/ versioning_class = URLPathVersioning def get(self,request,*args,**kwargs): # self.dispatch print(request.version) #打印的是版本 print(request.versioning_scheme) #打印的是对象 if request.version=='v2': return Response('我是版本二') elif request.version=='v1': return Response('我是版本一') else: return Response('...') views.py
注意:配置
REST_FRAMEWORK = { 'VERSION_PARAM':'version', 'DEFAULT_VERSION':'v1', 'ALLOWED_VERSIONS':['v1','v2'], # 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning" #如果加上这个配置就不用versioning_class = QueryParameterVersioning这样在指定了, 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning" }
补充:restful提供的反向生成(http://127.0.0.1:8080/api/v1/users/)

#urls.py #分发路由 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^api/(?P<version>[v1|v2]+)/', include('api.urls')), ] #api.urls.py urlpatterns = [ url(r'^users/', views.UserView1.as_view(), name='users-list'), ] #views.py 导入类 from rest_framework.reverse import reverse url = request.versioning_scheme.reverse(viewname='users-list',request=request) print(url) restfoamework反向解析
我们用django实现的,当前版本不一样的时候可以用这种方式。
from django.urls import reverse url = reverse(viewname='users-list',kwargs={'version':'v2'}) #指定的是v2就是v2,当你路径中输入v1的时候还是v2的路径 print(url) #/api/v2/users/
方式二:基于子域名传参

#分发url urlpatterns = [ #url(r'^admin/', admin.site.urls), url(r'^api/', include('api.urls')), ] urlpatterns = [ url(r'^users/', views.UsersView.as_view(),name='u'), ] class UsersView(APIView): def get(self,request,*args,**kwargs): self.dispatch print(request.version) # QueryParameterVersioning().detemiin_version() print(request.versioning_scheme) # QueryParameterVersioning() REST_FRAMEWORK = { 'VERSION_PARAM':'version', 'DEFAULT_VERSION':'v1', 'ALLOWED_VERSIONS':['v1','v2'], 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning" } # C:WindowsSystem32driversetc # vim /etc/hosts 127.0.0.1 v1.luffy.com 127.0.0.1 v2.luffy.com #配置ALLOWED_HOSTS = ['*'] 基于子域名传参
二、解析器
用处:request.data取值的时候才会用到
对请求的数据进行解析:是针对请求体进行解析的。表示服务器可以解析的数据格式的种类
django中的发送请求
#如果是这样的格式发送的数据,在POST里面有值 Content-Type: application/url-encoding..... request.body request.POST #如果是发送的json的格式,在POST里面是没有值的,在body里面有值,可通过decode,然后loads取值 Content-Type: application/json..... request.body request.POST
为了这种情况下每次都要decode,loads,显得麻烦,所以才有的解析器。弥补了django的缺点

客户端: Content-Type: application/json '{"name":"alex","age":123}' 服务端接收: 读取客户端发送的Content-Type的值 application/json parser_classes = [JSONParser,FormParser] #表示服务器可以解析的数据格式的种类 media_type_list = ['application/json','application/x-www-form-urlencoded'] 如果客户端的Content-Type的值和 application/json 匹配:JSONParser处理数据 如果客户端的Content-Type的值和 application/x-www-form-urlencoded 匹配:FormParser处理数据 配置: 单视图: class UsersView(APIView): parser_classes = [JSONParser,] 全局配置: REST_FRAMEWORK = { 'VERSION_PARAM':'version', 'DEFAULT_VERSION':'v1', 'ALLOWED_VERSIONS':['v1','v2'], # 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning" 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning", 'DEFAULT_PARSER_CLASSES':[ 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser', ] } class UserView(APIView): def get(self,request,*args,**kwargs): return Response('ok') def post(self,request,*args,**kwargs): print(request.data) #以后取值就在这里面去取值 return Response('...')
上传文件

1 from django.conf.urls import url, include 2 from web.views import TestView 3 4 urlpatterns = [ 5 url(r'test/(?P<filename>[^/]+)', TestView.as_view(), name='test'), 6 ]

#!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from rest_framework.parsers import FileUploadParser class TestView(APIView): parser_classes = [FileUploadParser, ] def post(self, request, filename, *args, **kwargs): print(filename) print(request.content_type) # 获取请求的值,并使用对应的JSONParser进行处理 print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值 print(request.POST) print(request.FILES) return Response('POST请求,响应内容') def put(self, request, *args, **kwargs): return Response('PUT请求,响应内容') views.py

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="http://127.0.0.1:8000/test/f1.numbers" method="post" enctype="multipart/form-data"> <input type="text" name="user" /> <input type="file" name="img"> <input type="submit" value="提交"> </form> </body> </html> upload.html
全局使用

REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES':[ 'rest_framework.parsers.JSONParser' 'rest_framework.parsers.FormParser' 'rest_framework.parsers.MultiPartParser' ] }