django2筆記之路由path語法的實(shí)現(xiàn)
9月23,Django 發(fā)布了2.0a1版本,這是一個(gè) feature freeze 版本,如果沒有什么意外的話,2.0正式版不會再增加新的功能了。按照以往的規(guī)律,預(yù)計(jì)正式版將在12月發(fā)布。
備注:Django 2.0 于12月2日已經(jīng)正式發(fā)布。 (鏈接)
2.0無疑是一個(gè)里程碑版本,移除了對 Python2.7 的支持,最少需要 3.4 以上,建議使用3.5以上的版本。
What's new in Django2.0 文檔中一共列出了三個(gè)新的特性:
更簡單的URL路由語法 (Simplified URL routing syntax)
admin應(yīng)用的針對移動設(shè)備的優(yōu)化改進(jìn)(Mobile-friendly contrib.admin)
支持SQL開窗表達(dá)式(Window expressions)
第一個(gè)特性,主要用于動態(tài)路由定義上。在Django2.0代碼實(shí)現(xiàn)中,主要的變化是新增了 django.urls.path 函數(shù),它允許使用一種更加簡潔、可讀的路由語法。比如之前的版本的代碼:
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
在新版本中也可以寫為:
path('articles/<int:year>/', views.year_archive),
新語法支持類型轉(zhuǎn)化,在上述的例子中, year_archive 函數(shù)接收到的year參數(shù)就變成整數(shù)而不是字符串。
如果你有接觸過 Flask 框架,就會發(fā)現(xiàn)和 Variable-Rules 的語法形式和功能都是相類似的。
一 問題引入
下面是 Django1.X 的一段代碼:
from django.conf.urls import url def year_archive(request, year): year = int(year) # convert str to int # Get articles from database def detail_view(request, article_id): pass def edit_view(request, article_id): pass def delete_view(request, article_id): pass urlpatterns = [ url('articles/(?P<year>[0-9]{4})/', year_archive), url('article/(?P<article_id>[a-zA-Z0-9]+)/detail/', detail_view), url('articles/(?P<article_id>[a-zA-Z0-9]+)/edit/', edit_view), url('articles/(?P<article_id>[a-zA-Z0-9]+)/delete/', delete_view), ]
考慮下這樣的兩個(gè)問題:
第一個(gè)問題,函數(shù) year_archive 中year參數(shù)是字符串類型的,因此需要先轉(zhuǎn)化為整數(shù)類型的變量值,當(dāng)然 year=int(year) 不會有諸如如TypeError或者ValueError的異常。那么有沒有一種方法,在url中,使得這一轉(zhuǎn)化步驟可以由Django自動完成?
第二個(gè)問題,三個(gè)路由中 article_id 在業(yè)務(wù)中表示同一個(gè)字段,使用同樣的正則表達(dá)式,但是你需要寫三遍,當(dāng)之后 article_id 規(guī)則改變后,需要同時(shí)修改三處代碼,那么有沒有一種方法,只需修改一處即可?
在 Django2.0 中,可以使用 path 解決以上的兩個(gè)問題。
二 使用示例
這是一個(gè)簡單的例子:
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>/', views.article_detail), ]
基本規(guī)則:
- 使用尖括號(<>)從url中捕獲值。
- 捕獲值中可以包含一個(gè)轉(zhuǎn)化器類型(converter type),比如使用 <int:name> 捕獲一個(gè)整數(shù)變量。若果沒有轉(zhuǎn)化器,將匹配任何字符串,當(dāng)然也包括了 / 字符。
- 無需添加前導(dǎo)斜杠。
以下是根據(jù) 2.0官方文檔 而整理的示例分析表:
請求URL | 匹配項(xiàng) | 視圖函數(shù)調(diào)用形式 |
---|---|---|
/articles/2005/03/ | 第3個(gè) | views.month_archive(request, year=2005, month=3) |
/articles/2003/ | 第1個(gè) | views.special_case_2003(request) |
/articles/2003 | 無 | - |
/articles/2003/03/building-a-django-site/ | 第4個(gè) | views.article_detail(request, year=2003, month=3, slug=”building-a-django-site”) |
三 path轉(zhuǎn)化器
文檔原文是Path converters,暫且翻譯為轉(zhuǎn)化器。
Django默認(rèn)支持以下5個(gè)轉(zhuǎn)化器:
- str,匹配除了路徑分隔符(/)之外的非空字符串,這是默認(rèn)的形式
- int,匹配正整數(shù),包含0。
- slug,匹配字母、數(shù)字以及橫杠、下劃線組成的字符串。
- uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
- path,匹配任何非空字符串,包含了路徑分隔符
四 自定義轉(zhuǎn)化器
4.1 定義
對于一些復(fù)雜或者復(fù)用的需要,可以定義自己的轉(zhuǎn)化器。轉(zhuǎn)化器是一個(gè)類或接口,它的要求有三點(diǎn):
- regex 類屬性,字符串類型
- to_python(self, value) 方法,value是由類屬性 regex 所匹配到的字符串,返回具體的Python變量值,以供Django傳遞到對應(yīng)的視圖函數(shù)中。
- to_url(self, value) 方法,和 to_python 相反,value是一個(gè)具體的Python變量值,返回其字符串,通常用于url反向引用。
先看看默認(rèn)的 IntConverter 和 StringConverter 是怎么實(shí)現(xiàn)的:
class IntConverter: regex = '[0-9]+' def to_python(self, value): return int(value) def to_url(self, value): return str(value) class StringConverter: regex = '[^/]+' def to_python(self, value): return value def to_url(self, value): return value
第二個(gè)例子,是自己實(shí)現(xiàn)的4位年份的轉(zhuǎn)化器。
class FourDigitYearConverter: regex = '[0-9]{4}' def to_python(self, value): return int(value) def to_url(self, value): return '%04d' % value
4.2 注冊
使用register_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), ... ]
五 使用正則表達(dá)式
如果上述的paths和converters還是無法滿足需求,也可以使用正則表達(dá)式,這時(shí)應(yīng)當(dāng)使用 django.urls.re_path函數(shù)。
在Python正則表達(dá)式中,命名式分組語法為 (?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>[^/]+)/', views.article_detail), ]
這段代碼和之前的代碼實(shí)現(xiàn)了基本的功能,但是還是有一些區(qū)別:
- 這里的代碼匹配更加嚴(yán)格,比如year=10000在這里就無法匹配。
- 傳遞給視圖函數(shù)的變量都是字符串類型,這點(diǎn)和 url 是一致的。
無命名分組
一般來說,不建議使用這種方式,因?yàn)橛锌赡芤肫缌x,甚至錯(cuò)誤。
六 Import變動
django.urls.path 可以看成是 django.conf.urls.url 的增強(qiáng)形式。
為了方便,其引用路徑也有所變化,請注意下 urls 包路徑的變更,不再是 conf 的子包了,目前和 views 、conf 一樣,被認(rèn)為是 Django 的核心組件。
1.X | 2.0 | 備注 |
---|---|---|
- | django.urls.path | 新增,url的增強(qiáng)版 |
django.conf.urls.include | django.urls.include | 路徑變更 |
django.conf.urls.url | django.urls.re_path | 異名同功能,url不會立即廢棄 |
七 代碼改寫
將“問題引入”一節(jié)的代碼使用新的path函數(shù)可以改寫如下:
from django.urls import path, register_converter from django.urls.converters import SlugConverter class FourDigitYearConverter: regex = '[0-9]{4}' def to_python(self, value): return int(value) def to_url(self, value): return '%04d' % value register_converter(SlugConverter, 'article_id') register_converter(FourDigitYearConverter, 'year') def year_archive(request, year): print(type(year)) # <class 'int'> # Get articles from database def detail_view(request, article_id): pass def edit_view(request, article_id): pass def delete_view(request, article_id): pass urlpatterns = [ path('articles/<year:year>/', year_archive), path('article/<article_id:article_id>/detail/', detail_view), path('articles/<article_id:article_id>/edit/', edit_view), path('articles/<article_id:article_id>/delete/', delete_view), ]
八 總結(jié)
第一,目前 路由(url)到視圖(View)的流程可以概括為四個(gè)步驟:
1.url匹配
2.正則捕獲
3.變量類型轉(zhuǎn)化
4.視圖調(diào)用
Django2.0 和之前相比多了 變量類型轉(zhuǎn)化 這一步驟。
第二,新的path語法可以解決一下以下幾個(gè)場景:
- 類型自動轉(zhuǎn)化
- 公用正則表達(dá)式
了解更多:http://www.dbjr.com.cn/article/165591.htm
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python實(shí)現(xiàn)的HMacMD5加密算法示例
這篇文章主要介紹了Python實(shí)現(xiàn)的HMacMD5加密算法,簡單說明了HMAC-MD5加密算法的概念、原理并結(jié)合實(shí)例形式分析了Python實(shí)現(xiàn)HMAC-MD5加密算法的相關(guān)操作技巧,,末尾還附帶了Java實(shí)現(xiàn)HMAC-MD5加密算法的示例,需要的朋友可以參考下2018-04-04Python json模塊與jsonpath模塊區(qū)別詳解
這篇文章主要介紹了Python json模塊與jsonpath模塊區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03Python實(shí)現(xiàn)提取PDF簡歷信息并存入Excel
作為人力資源部的小伙伴,常常需要把他人投遞的PDF簡歷資料里的關(guān)鍵信息數(shù)據(jù),提取到excel表中匯總,這個(gè)時(shí)候用Python實(shí)現(xiàn)最合適, 快來學(xué)習(xí)一下如何實(shí)現(xiàn)吧2022-04-04Python構(gòu)建一個(gè)文檔掃描器的實(shí)現(xiàn)
本文主要介紹了Python構(gòu)建一個(gè)文檔掃描器的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03python實(shí)現(xiàn)ip地址的包含關(guān)系判斷
這篇文章主要介紹了python實(shí)現(xiàn)ip地址的包含關(guān)系判斷,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02