版本控制:當程序愈來愈大,後期須要再加入一些功能或者進行二次開發時就須要加上版本號了。html
以前咱們在沒有接觸rest_framework以前通常是如下這種方式來實現的python
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來實現,主要有兩種方式web
方式一:基於urldjango
#基於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/
具體操做json
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
注意:配置vim
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/)api
#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/
方式二:基於子域名傳參restful
#分發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:\Windows\System32\drivers\etc # vim /etc/hosts 127.0.0.1 v1.luffy.com 127.0.0.1 v2.luffy.com #配置ALLOWED_HOSTS = ['*'] 基於子域名傳參
用處:request.data取值的時候纔會用到app
對請求的數據進行解析:是針對請求體進行解析的。表示服務器能夠解析的數據格式的種類
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' ] }