day53-Django之路由系统
13 form表單上傳文件.mp4 12 JsonResponse對(duì)象.mp4 11 虛擬環(huán)境與django版本區(qū)別.mp4 10 偽靜態(tài).mp4 09 名稱(chēng)空間.mp4 08 路由分發(fā).mp4 07 有名無(wú)名反向解析.mp4 06 反向解析.mp4 05 有名和無(wú)名分組.mp4 04 路由匹配.mp4 03 django請(qǐng)求生命周期.mp4 02 圖書(shū)管理系統(tǒng)表設(shè)計(jì).mp4 01 昨日內(nèi)容回顧.mp4
URLS路由配置
URL配置(URLconf)就像Django 所支撐網(wǎng)站的目錄。它的本質(zhì)是URL與要為該URL調(diào)用的視圖函數(shù)之間的映射表。
你就是以這種方式告訴Django,對(duì)于這個(gè)URL調(diào)用這段代碼,對(duì)于那個(gè)URL調(diào)用那段代碼。
1.1?URLconf配置
基本格式:
from django.conf.urls import url urlpatterns = [ url(正則表達(dá)式, views視圖函數(shù),參數(shù),別名), ]注意:
Django 2.0版本中的路由系統(tǒng)已經(jīng)替換成下面的寫(xiě)法(官方文檔):
from django.http import HttpResponse import datetimedef current_datetime(request):now = datetime.datetime.now()html = "<html><body>It is now %s.</body></html>" % nowreturn HttpResponse(html)參數(shù)說(shuō)明:
- 正則表達(dá)式:一個(gè)正則表達(dá)式字符串
- views視圖函數(shù):一個(gè)可調(diào)用對(duì)象,通常為一個(gè)視圖函數(shù)或一個(gè)指定視圖函數(shù)路徑的字符串
- 參數(shù):可選的要傳遞給視圖函數(shù)的默認(rèn)參數(shù)(字典形式)
- 別名:一個(gè)可選的name參數(shù)
1.2?正則表達(dá)式詳解
基本配置
from django.conf.urls import url from . import viewsurlpatterns = [url(r'^articles/2003/$', views.special_case_2003),url(r'^articles/([0-9]{4})/$', views.year_archive),url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail), ]注意事項(xiàng)
補(bǔ)充說(shuō)明
# 是否開(kāi)啟URL訪(fǎng)問(wèn)地址后面不為/跳轉(zhuǎn)至帶有/的路徑的配置項(xiàng) APPEND_SLASH=TrueDjango settings.py配置文件中默認(rèn)沒(méi)有 APPEND_SLASH 這個(gè)參數(shù),但 Django 默認(rèn)這個(gè)參數(shù)為 APPEND_SLASH = True。 其作用就是自動(dòng)在網(wǎng)址結(jié)尾加'/'。
其效果就是:
我們定義了urls.py:
from django.conf.urls import url from app01 import viewsurlpatterns = [url(r'^blog/$', views.blog), ]訪(fǎng)問(wèn) http://www.example.com/blog 時(shí),默認(rèn)將網(wǎng)址自動(dòng)轉(zhuǎn)換為 http://www.example/com/blog/ 。
如果在settings.py中設(shè)置了?APPEND_SLASH=False,此時(shí)我們?cè)僬?qǐng)求 http://www.example.com/blog 時(shí)就會(huì)提示找不到頁(yè)面。
1.3?分組命名匹配
上面的示例使用簡(jiǎn)單的正則表達(dá)式分組匹配(通過(guò)圓括號(hào))來(lái)捕獲URL中的值并以位置參數(shù)形式傳遞給視圖。
在更高級(jí)的用法中,可以使用分組命名匹配的正則表達(dá)式組來(lái)捕獲URL中的值并以關(guān)鍵字參數(shù)形式傳遞給視圖。
在Python的正則表達(dá)式中,分組命名正則表達(dá)式組的語(yǔ)法是(?P<name>pattern),其中name是組的名稱(chēng),pattern是要匹配的模式。
下面是以上URLconf 使用命名組的重寫(xiě):
from django.conf.urls import url from . import viewsurlpatterns = [url(r'^articles/2003/$', views.special_case_2003),url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail), ]這個(gè)實(shí)現(xiàn)與前面的示例完全相同,只有一個(gè)細(xì)微的差別:捕獲的值作為關(guān)鍵字參數(shù)而不是位置參數(shù)傳遞給視圖函數(shù)。
例如,針對(duì)url?/articles/2017/12/相當(dāng)于按以下方式調(diào)用視圖函數(shù):
views.month_archive(request, year="2017", month="12")?
在實(shí)際應(yīng)用中,使用分組命名匹配的方式可以讓你的URLconf 更加明晰且不容易產(chǎn)生參數(shù)順序問(wèn)題的錯(cuò)誤,但是有些開(kāi)發(fā)人員則認(rèn)為分組命名組語(yǔ)法太丑陋、繁瑣。
至于究竟應(yīng)該使用哪一種,你可以根據(jù)自己的喜好來(lái)決定。
URLconf匹配的位置
URLconf 在請(qǐng)求的URL 上查找,將它當(dāng)做一個(gè)普通的Python 字符串。不包括GET和POST參數(shù)以及域名。
例如,http://www.example.com/myapp/ 請(qǐng)求中,URLconf 將查找myapp/。
在http://www.example.com/myapp/?page=3 請(qǐng)求中,URLconf 仍將查找myapp/。
URLconf 不檢查請(qǐng)求的方法。換句話(huà)講,所有的請(qǐng)求方法 —— 同一個(gè)URL的POST、GET、HEAD等等 —— 都將路由到相同的函數(shù)。
捕獲的參數(shù)永遠(yuǎn)都是字符串
每個(gè)在URLconf中捕獲的參數(shù)都作為一個(gè)普通的Python字符串傳遞給視圖,無(wú)論正則表達(dá)式使用的是什么匹配方式。例如,下面這行URLconf 中:
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),?傳遞到視圖函數(shù)views.year_archive()?中的year?參數(shù)永遠(yuǎn)是一個(gè)字符串類(lèi)型。
視圖函數(shù)中指定默認(rèn)值
# urls.py中 from django.conf.urls import urlfrom . import viewsurlpatterns = [url(r'^blog/$', views.page),url(r'^blog/page(?P<num>[0-9]+)/$', views.page), ]# views.py中,可以為num指定默認(rèn)值 def page(request, num="1"):pass在上面的例子中,兩個(gè)URL模式指向相同的view - views.page - 但是第一個(gè)模式并沒(méi)有從URL中捕獲任何東西。
如果第一個(gè)模式匹配上了,page()函數(shù)將使用其默認(rèn)參數(shù)num=“1”,如果第二個(gè)模式匹配,page()將使用正則表達(dá)式捕獲到的num值。
include其他的URLconfs
#At any point, your urlpatterns can “include” other URLconf modules. This #essentially “roots” a set of URLs below other ones.#For example, here’s an excerpt of the URLconf for the Django website itself. #It includes a number of other URLconfs:from django.conf.urls import include, urlurlpatterns = [url(r'^admin/', admin.site.urls),url(r'^blog/', include('blog.urls')), # 可以包含其他的URLconfs文件 ]
?
1.4?傳遞額外的參數(shù)給視圖函數(shù)(了解)
URLconfs 具有一個(gè)鉤子,讓你傳遞一個(gè)Python 字典作為額外的參數(shù)傳遞給視圖函數(shù)。
django.conf.urls.url()?函數(shù)可以接收一個(gè)可選的第三個(gè)參數(shù),它是一個(gè)字典,表示想要傳遞給視圖函數(shù)的額外關(guān)鍵字參數(shù)。
例如:
from django.conf.urls import url from . import viewsurlpatterns = [url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}), ]在這個(gè)例子中,對(duì)于/blog/2005/請(qǐng)求,Django 將調(diào)用views.year_archive(request, year='2005', foo='bar')。
這個(gè)技術(shù)在Syndication 框架中使用,來(lái)傳遞元數(shù)據(jù)和選項(xiàng)給視圖。
1.5?命名URL和URL反向解析
在使用Django 項(xiàng)目時(shí),一個(gè)常見(jiàn)的需求是獲得URL的最終形式,以用于嵌入到生成的內(nèi)容中(視圖中和顯示給用戶(hù)的URL等)或者用于處理服務(wù)器端的導(dǎo)航(重定向等)。
人們強(qiáng)烈希望不要硬編碼這些URL(費(fèi)力、不可擴(kuò)展且容易產(chǎn)生錯(cuò)誤)或者設(shè)計(jì)一種與URLconf 毫不相關(guān)的專(zhuān)門(mén)的URL 生成機(jī)制,因?yàn)檫@樣容易導(dǎo)致一定程度上產(chǎn)生過(guò)期的URL。
換句話(huà)講,需要的是一個(gè)DRY 機(jī)制。除了其它有點(diǎn),它還允許設(shè)計(jì)的URL 可以自動(dòng)更新而不用遍歷項(xiàng)目的源代碼來(lái)搜索并替換過(guò)期的URL。
獲取一個(gè)URL 最開(kāi)始想到的信息是處理它視圖的標(biāo)識(shí)(例如名字),查找正確的URL 的其它必要的信息有視圖參數(shù)的類(lèi)型(位置參數(shù)、關(guān)鍵字參數(shù))和值。
Django 提供一個(gè)辦法是讓URL 映射是URL 設(shè)計(jì)唯一的地方。你填充你的URLconf,然后可以雙向使用它:
- 根據(jù)用戶(hù)/瀏覽器發(fā)起的URL 請(qǐng)求,它調(diào)用正確的Django 視圖,并從URL 中提取它的參數(shù)需要的值。
- 根據(jù)Django 視圖的標(biāo)識(shí)和將要傳遞給它的參數(shù)的值,獲取與之關(guān)聯(lián)的URL。
第一種方式是我們?cè)谇懊娴恼鹿?jié)中一直討論的用法。第二種方式叫做反向解析URL、反向URL 匹配、反向URL 查詢(xún)或者簡(jiǎn)單的URL 反查。
在需要URL 的地方,對(duì)于不同層級(jí),Django 提供不同的工具用于URL 反查:
- 在模板中:使用url模板標(biāo)簽。
- 在Python 代碼中:使用django.core.urlresolvers.reverse() 函數(shù)。
- 在更高層的與處理Django 模型實(shí)例相關(guān)的代碼中:使用get_absolute_url() 方法。
上面說(shuō)了一大堆,你可能并沒(méi)有看懂。(那是官方文檔的生硬翻譯)。
咱們簡(jiǎn)單來(lái)說(shuō)就是可以給我們的URL匹配規(guī)則起個(gè)名字,一個(gè)URL匹配模式起一個(gè)名字。
這樣我們以后就不需要寫(xiě)死URL代碼了,只需要通過(guò)名字來(lái)調(diào)用當(dāng)前的URL。
舉個(gè)簡(jiǎn)單的例子:
url(r'^home', views.home, name='home'), # 給我的url匹配模式起名為 home url(r'^index/(\d*)', views.index, name='index'), # 給我的url匹配模式起名為index?
這樣:
在模板里面可以這樣引用:
{% url 'home' %}在views函數(shù)中可以這樣引用:
from django.urls import reversereverse("index", args=("2018", ))?
例子:
考慮下面的URLconf:
?
根據(jù)這里的設(shè)計(jì),某一年nnnn對(duì)應(yīng)的歸檔的URL是/articles/nnnn/。
你可以在模板的代碼中使用下面的方法獲得它們:
<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a><ul> {% for yearvar in year_list %} <li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li> {% endfor %} </ul>?
在Python 代碼中,這樣使用:
from django.urls import reverse from django.shortcuts import redirectdef redirect_to_year(request):# ...year = 2006# ...return redirect(reverse('news-year-archive', args=(year,)))?
如果出于某種原因決定按年歸檔文章發(fā)布的URL應(yīng)該調(diào)整一下,那么你將只需要修改URLconf 中的內(nèi)容。
在某些場(chǎng)景中,一個(gè)視圖是通用的,所以在URL 和視圖之間存在多對(duì)一的關(guān)系。對(duì)于這些情況,當(dāng)反查URL 時(shí),只有視圖的名字還不夠。
注意:
為了完成上面例子中的URL 反查,你將需要使用命名的URL 模式。URL 的名稱(chēng)使用的字符串可以包含任何你喜歡的字符。不只限制在合法的Python 名稱(chēng)。
當(dāng)命名你的URL 模式時(shí),請(qǐng)確保使用的名稱(chēng)不會(huì)與其它應(yīng)用中名稱(chēng)沖突。如果你的URL 模式叫做comment,而另外一個(gè)應(yīng)用中也有一個(gè)同樣的名稱(chēng),當(dāng)你在模板中使用這個(gè)名稱(chēng)的時(shí)候不能保證將插入哪個(gè)URL。
在URL 名稱(chēng)中加上一個(gè)前綴,比如應(yīng)用的名稱(chēng),將減少?zèng)_突的可能。我們建議使用myapp-comment?而不是comment。
1|6命名空間模式
即使不同的APP使用相同的URL名稱(chēng),URL的命名空間模式也可以讓你唯一反轉(zhuǎn)命名的URL。
舉個(gè)例子:
project中的urls.py
from django.conf.urls import url, includeurlpatterns = [url(r'^app01/', include('app01.urls', namespace='app01')),url(r'^app02/', include('app02.urls', namespace='app02')), ]?
app01中的urls.py
from django.conf.urls import url from app01 import viewsapp_name = 'app01' urlpatterns = [url(r'^(?P<pk>\d+)/$', views.detail, name='detail') ]?
app02中的urls.py
from django.conf.urls import url from app02 import viewsapp_name = 'app02' urlpatterns = [url(r'^(?P<pk>\d+)/$', views.detail, name='detail') ]?
現(xiàn)在,我的兩個(gè)app中 url名稱(chēng)重復(fù)了,我反轉(zhuǎn)URL的時(shí)候就可以通過(guò)命名空間的名稱(chēng)得到我當(dāng)前的URL。
語(yǔ)法:
'命名空間名稱(chēng):URL名稱(chēng)'
模板中使用:
{% url 'app01:detail' pk=12 pp=99 %}views中的函數(shù)中使用
v = reverse('app01:detail', kwargs={'pk':11})?
?這樣即使app中URL的命名相同,我也可以反轉(zhuǎn)得到正確的URL了。
轉(zhuǎn)載于:https://www.cnblogs.com/Ryan-Yuan/p/11537852.html
總結(jié)
以上是生活随笔為你收集整理的day53-Django之路由系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 星地融合→→→6G移动通信关键技术的未来
- 下一篇: 11 操作系统第三章 内存管理 内存的基