Django2.0於2017年12月2日已經正式發布。Django2.0支持Python3.4,3.5以及3.6,移除了對Python2.7的支持。官方強烈建議Python 3.x使用最新的版本。
在Django2.0其中一個新特性為:簡化Url路由的語法。
在代碼上主要體現在新增了django.urls.path函數,它帶來了更簡潔、更可讀的路由語法,如:
原來的url
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
Django2.0新語法
path('articles/<int:year>/', views.year_archive),
新語法支持url參數的類型轉化。例子里的year_archive函數接收到的year參數作為參數,並且會自動轉換year為整型而不是字符串。
在Django1.x里,我們需要對year做類型轉換:
def year_archive(request, year):
year = int(year)
URL參數捕獲
在新的語法里,url字符串有以下規則:
- 在url里使用尖括號“<>”來捕獲值
- 尖括號捕獲值的格式<converter:name>。其中converter為路徑轉換器,name為參數名,如<int:year>。對於捕獲的值沒有路徑轉換器,那么它會匹配除了斜杠"/"外的所有字符作為捕獲的值。
- url不需要以斜杠開頭。
代碼示例
from django.urls import path
from . import views
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<int:year>/', views.year_archive),
path('articles/<int:year>/<int:month>/', views.month_archive),
path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
]
匹配示例
- /articles/2005/03/:匹配到第3個規則,調用views.month_archive(request, year=2005, month=3)
- /articles/2003/:匹配到第1個規則,調用views.special_case_2003(request)
- /articles/2003:沒有匹配到規則,原因是所有的規則都是以斜杠結尾
- /articles/2003/03/building-a-django-site/:匹配到第4個規則,調用views.article_detail(request, year=2003, month=3, slug=”building-a-django-site”)
Path Converter
url里捕獲的值使用Path Converter來對值做轉換,如類型轉換。Django2.0自帶了默人的Path Converter,同時也支持自定義Path Conveter。
默認Path converter
Django2.0自帶的PathConveter包括:
- str:匹配除了路徑分隔符(/)之外的非空字符串,如果沒有轉換器,默認使用str作為轉換器。
- int:匹配0及正整數。
- slug:匹配字母、數字以及橫杠、下划線組成的字符串。
- uuid:匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
- path:匹配任何非空字符串,包含了路徑分隔符(/)
例子: path('image_codes/<uuid>', views.xxxx) image_codes是前綴,<uuid>是django自帶的配合器寫法,得到的是一個UUID對象, 在視圖方法中通過參數來接受這個 uuid 例如: def get(self,request,uuid) 可以打印這個UUID 得到是一個前端傳過來的uuid.
注冊自定義Path Converter
當默認的Path Converter不能滿足需求時,Django2.0支持用戶注冊自定義的Path Converter。
Path Converter是一個類,定義Converter類需要包含下面的屬性或方法:
- regex屬性,字符串類型
- to_python(self, value) 方法,它處理將匹配的字符串轉換為應該傳遞給view函數的類型。 如果它不能轉換給定的值,它應該拋出ValueError。
- to_url(self, value) 方法,和 to_python 相反,它會將Python類型轉換為在URL中使用的字符串。
示例
定義Path Converter
class FourDigitYearConverter:
regex = '[0-9]{4}'
def to_python(self, value):
return int(value)
def to_url(self, value):
return '%04d' % value
使用register_converter()注冊Converter到url配置里:
from django.urls import register_converter, path
from . import converters, views
register_converter(converters.FourDigitYearConverter, 'yyyy')
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<yyyy:year>/', views.year_archive),
...
]
正則表達式匹配
Django2.0也支持我們使用正則表達式來捕獲值。注意,用正則表達式捕獲值,需要使用re_path(),而不是前面介紹的path()。
正則表達式建議使用命名正則表達式組,語法如下:
(?P<name>pattern)
其中,尖括號里的name為分組名,pattern為正則表達式。
前面的示例可以使用正則表達式修改為:
from django.urls import path, re_path
from . import views
urlpatterns = [
path('articles/2003/', views.special_case_2003),
re_path('articles/(?P<year>[0-9]{4})/', views.year_archive),
re_path('articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/', views.month_archive),
re_path('articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-_]+)/', views.article_detail),
]
與前面的示例不同點:
- 這里的代碼匹配更加嚴格,比如year為10000就無法匹配,因為它超出了正則規定的4位數
- 傳給view函數的參數為字符串類型,這點和 Django使用url 是一樣的。
設置默認值
在path里支持對view設置默認值。
from django.urls import path
from . import views
urlpatterns = [
path('blog/', views.page),
path('blog/page<int:num>/', views.page),
]
# View (in blog/views.py)
def page(request, num=1):
# Output the appropriate page of blog entries, according to num.
...
page函數num的默認值設置為1.