框架之開發中的版本傳遞問題
一、通過get傳參的方式
1.自定義接收參數類
class ParamVersion(object):
def determine_version(self, request, *args, **kwargs):
version = request.query_params.get('version')
return version
class UsersView(APIView):
versioning_class = ParamVersion
# 注意:這里接收參數的類是一個,所以class為單數,后邊的類只能有一個
def get(self, request, *args, **kwargs):
print(request.version)
# 通過參數類返回的version信息直接封裝在request中,可以通過request.version來獲取
return Response("詳情頁面")
2.使用框架封裝好的組件來實現
-
在視圖文件中設置參數的接收,這里需呀導入QueryParameterVersioning類
from rest_framework.versioning import QueryParameterVersioning class UsersView(API): versioning_class = QueryParameterVersioning def get(self, request, *args, **kwargs): print(request.version) return Response("詳情頁面")
-
在settings.py文件中對提交的版本信息進行設置
REST_FRAMEWORK = [ 'DEFAULT_VERSION': 'V1', # 當開發者不傳遞參數時默認的版本號 'ALLOWED_VERSIONS': ['V1', 'V2', 'V3'], # 整個開發過程中允許使用的版本號 'VERSION_PARAM': 'version' # 當傳遞版本信息時,版本值對應的key值,即 ?version=V1 ]
二、將版本信息寫入到url中
這個方式需要用到的是URLPathVersioning類
-
url路由的分配
urlpatterns = [ path('users/<slug: version>/', views.UsersView.as_view()), 注意:2.0版本以后再傳遞的變量如果是str用到的是slug ]
-
視圖類設置
from rest_framework.versioning import URLPathVersioning class UsersView(APIView): versioning_class = URLPathVersioning def get(self, request, *args, **kwargs): print(request.version) return Response("詳情頁面")
-
傳遞版本信息的設置和get中的全局設置是一樣的,默認版本號、允許的版本列表、版本key
Note
需要注意的是,開發者可以正向的傳遞版本信息,程序也可以反向的獲取url地址
- 獲取處理版本的對象信息:request.versioning_scheme
- 反向獲取url: request.versioning_scheme.reverse(viewname='url的別名', request=request)
三、Django 2.0 url()到path()速查表
2018年5月2日丹尼爾·赫珀DJANGO的,WEB開發
Django 2.0引入了一種定義URL的新方法,該方法大大簡化了如何捕獲參數。
在早期版本的Django中,您必須使用該url()方法並傳遞帶有命名捕獲組的正則表達式來捕獲URL參數。
url(r'^posts/(?P<post_id>[0-9]+)/$', post_detail_view)
在Django 2.0中,您將該path()方法與路徑轉換器一起使用以捕獲URL參數。
path('posts/int:post_id/', post_detail_view)
path()總是匹配完整的路徑,path('account/login/')等同於url('^account/login/$')。
尖括號(int:post_id)中的部分捕獲了傳遞給視圖的URL參數。冒號(post_id)后面的部分定義參數的名稱,冒號(int)前面的部分命名路徑轉換器。
路徑轉換器不僅易於閱讀,而且還帶來了一個新功能:路徑轉換器可以在將參數傳遞給視圖之前將參數轉換為適當的類型。
早期版本的Django只是將匹配的字符串傳遞給視圖,這意味着您必須編寫以下代碼:
url(r'^posts/(?P<post_id>[0-9]+)/$', post_detail_view)
def post_detail_view(request, post_id):
post_id = int(post_id)
...
從Django 2.0開始,您只需編寫以下代碼:
path('posts/<int:post_id>')
def post_detail_view(request, post_id):
...
Django 2.0隨附五個內置轉換器:
-
str
匹配任何非空字符串,但路徑分隔符“ /”除外。如果表達式中不包含轉換器,則為默認設置。
示例:'best_product_ever!-123.html'
返回字符串(str)。
等效正則表達式:[^/]+ -
int
匹配零或任何正整數。
示例:'1234'
返回一個整數(int)。
等效正則表達式:[0-9]+ -
slug
匹配由ASCII字母或數字以及連字符和下划線字符組成的任何字符串。
返回字符串(str)。
示例:'building-your-1st-django-site'
等效正則表達式:[-a-zA-Z0-9_]+ -
uuid
匹配格式化的UUID。為防止多個URL映射到同一頁面,必須包括破折號並且字母必須小寫。
返回一個UUID實例(uuid.UUID)。
示例:'075194d3-6885-417e-a8a8-6c931e272f00'
等效正則表達式:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} -
path
匹配任何非空字符串,包括路徑分隔符“ /”。這使您可以與完整的URL路徑進行匹配,而不僅僅是與str一樣的URL路徑的一部分。
示例:'/path/to/file'
返回字符串(str)。
等效正則表達式:'.+'
如果預定義的路徑轉換器不適合需求,則可以注冊自定義路徑轉換器,這可以完成一些技巧,例如將URL參數直接轉換為模型實例。另外,您仍然可以使用re_path()代替來使用良好的ol'正則表達式path()。
from django.urls import re_path
re_path(r'posts/(?P<post_id>[0-9]+)/$', post_detail_view)
順便說一句,舊url()功能仍然可用,因此現在無需更改所有URL定義。
新path()方法極大地簡化了URL處理。我與Django合作已有10多年了,至今仍然不記得如何定義命名的正則表達式捕獲組。此外,手動執行類型轉換會違反DRY原理。