day53-Django之路由系统
13 form表單上傳文件.mp4 12 JsonResponse對象.mp4 11 虛擬環境與django版本區別.mp4 10 偽靜態.mp4 09 名稱空間.mp4 08 路由分發.mp4 07 有名無名反向解析.mp4 06 反向解析.mp4 05 有名和無名分組.mp4 04 路由匹配.mp4 03 django請求生命周期.mp4 02 圖書管理系統表設計.mp4 01 昨日內容回顧.mp4
URLS路由配置
URL配置(URLconf)就像Django 所支撐網站的目錄。它的本質是URL與要為該URL調用的視圖函數之間的映射表。
你就是以這種方式告訴Django,對于這個URL調用這段代碼,對于那個URL調用那段代碼。
1.1?URLconf配置
基本格式:
from django.conf.urls import url urlpatterns = [ url(正則表達式, views視圖函數,參數,別名), ]注意:
Django 2.0版本中的路由系統已經替換成下面的寫法(官方文檔):
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)參數說明:
- 正則表達式:一個正則表達式字符串
- views視圖函數:一個可調用對象,通常為一個視圖函數或一個指定視圖函數路徑的字符串
- 參數:可選的要傳遞給視圖函數的默認參數(字典形式)
- 別名:一個可選的name參數
1.2?正則表達式詳解
基本配置
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), ]注意事項
補充說明
# 是否開啟URL訪問地址后面不為/跳轉至帶有/的路徑的配置項 APPEND_SLASH=TrueDjango settings.py配置文件中默認沒有 APPEND_SLASH 這個參數,但 Django 默認這個參數為 APPEND_SLASH = True。 其作用就是自動在網址結尾加'/'。
其效果就是:
我們定義了urls.py:
from django.conf.urls import url from app01 import viewsurlpatterns = [url(r'^blog/$', views.blog), ]訪問 http://www.example.com/blog 時,默認將網址自動轉換為 http://www.example/com/blog/ 。
如果在settings.py中設置了?APPEND_SLASH=False,此時我們再請求 http://www.example.com/blog 時就會提示找不到頁面。
1.3?分組命名匹配
上面的示例使用簡單的正則表達式分組匹配(通過圓括號)來捕獲URL中的值并以位置參數形式傳遞給視圖。
在更高級的用法中,可以使用分組命名匹配的正則表達式組來捕獲URL中的值并以關鍵字參數形式傳遞給視圖。
在Python的正則表達式中,分組命名正則表達式組的語法是(?P<name>pattern),其中name是組的名稱,pattern是要匹配的模式。
下面是以上URLconf 使用命名組的重寫:
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), ]這個實現與前面的示例完全相同,只有一個細微的差別:捕獲的值作為關鍵字參數而不是位置參數傳遞給視圖函數。
例如,針對url?/articles/2017/12/相當于按以下方式調用視圖函數:
views.month_archive(request, year="2017", month="12")?
在實際應用中,使用分組命名匹配的方式可以讓你的URLconf 更加明晰且不容易產生參數順序問題的錯誤,但是有些開發人員則認為分組命名組語法太丑陋、繁瑣。
至于究竟應該使用哪一種,你可以根據自己的喜好來決定。
URLconf匹配的位置
URLconf 在請求的URL 上查找,將它當做一個普通的Python 字符串。不包括GET和POST參數以及域名。
例如,http://www.example.com/myapp/ 請求中,URLconf 將查找myapp/。
在http://www.example.com/myapp/?page=3 請求中,URLconf 仍將查找myapp/。
URLconf 不檢查請求的方法。換句話講,所有的請求方法 —— 同一個URL的POST、GET、HEAD等等 —— 都將路由到相同的函數。
捕獲的參數永遠都是字符串
每個在URLconf中捕獲的參數都作為一個普通的Python字符串傳遞給視圖,無論正則表達式使用的是什么匹配方式。例如,下面這行URLconf 中:
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),?傳遞到視圖函數views.year_archive()?中的year?參數永遠是一個字符串類型。
視圖函數中指定默認值
# 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指定默認值 def page(request, num="1"):pass在上面的例子中,兩個URL模式指向相同的view - views.page - 但是第一個模式并沒有從URL中捕獲任何東西。
如果第一個模式匹配上了,page()函數將使用其默認參數num=“1”,如果第二個模式匹配,page()將使用正則表達式捕獲到的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?傳遞額外的參數給視圖函數(了解)
URLconfs 具有一個鉤子,讓你傳遞一個Python 字典作為額外的參數傳遞給視圖函數。
django.conf.urls.url()?函數可以接收一個可選的第三個參數,它是一個字典,表示想要傳遞給視圖函數的額外關鍵字參數。
例如:
from django.conf.urls import url from . import viewsurlpatterns = [url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}), ]在這個例子中,對于/blog/2005/請求,Django 將調用views.year_archive(request, year='2005', foo='bar')。
這個技術在Syndication 框架中使用,來傳遞元數據和選項給視圖。
1.5?命名URL和URL反向解析
在使用Django 項目時,一個常見的需求是獲得URL的最終形式,以用于嵌入到生成的內容中(視圖中和顯示給用戶的URL等)或者用于處理服務器端的導航(重定向等)。
人們強烈希望不要硬編碼這些URL(費力、不可擴展且容易產生錯誤)或者設計一種與URLconf 毫不相關的專門的URL 生成機制,因為這樣容易導致一定程度上產生過期的URL。
換句話講,需要的是一個DRY 機制。除了其它有點,它還允許設計的URL 可以自動更新而不用遍歷項目的源代碼來搜索并替換過期的URL。
獲取一個URL 最開始想到的信息是處理它視圖的標識(例如名字),查找正確的URL 的其它必要的信息有視圖參數的類型(位置參數、關鍵字參數)和值。
Django 提供一個辦法是讓URL 映射是URL 設計唯一的地方。你填充你的URLconf,然后可以雙向使用它:
- 根據用戶/瀏覽器發起的URL 請求,它調用正確的Django 視圖,并從URL 中提取它的參數需要的值。
- 根據Django 視圖的標識和將要傳遞給它的參數的值,獲取與之關聯的URL。
第一種方式是我們在前面的章節中一直討論的用法。第二種方式叫做反向解析URL、反向URL 匹配、反向URL 查詢或者簡單的URL 反查。
在需要URL 的地方,對于不同層級,Django 提供不同的工具用于URL 反查:
- 在模板中:使用url模板標簽。
- 在Python 代碼中:使用django.core.urlresolvers.reverse() 函數。
- 在更高層的與處理Django 模型實例相關的代碼中:使用get_absolute_url() 方法。
上面說了一大堆,你可能并沒有看懂。(那是官方文檔的生硬翻譯)。
咱們簡單來說就是可以給我們的URL匹配規則起個名字,一個URL匹配模式起一個名字。
這樣我們以后就不需要寫死URL代碼了,只需要通過名字來調用當前的URL。
舉個簡單的例子:
url(r'^home', views.home, name='home'), # 給我的url匹配模式起名為 home url(r'^index/(\d*)', views.index, name='index'), # 給我的url匹配模式起名為index?
這樣:
在模板里面可以這樣引用:
{% url 'home' %}在views函數中可以這樣引用:
from django.urls import reversereverse("index", args=("2018", ))?
例子:
考慮下面的URLconf:
?
根據這里的設計,某一年nnnn對應的歸檔的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,)))?
如果出于某種原因決定按年歸檔文章發布的URL應該調整一下,那么你將只需要修改URLconf 中的內容。
在某些場景中,一個視圖是通用的,所以在URL 和視圖之間存在多對一的關系。對于這些情況,當反查URL 時,只有視圖的名字還不夠。
注意:
為了完成上面例子中的URL 反查,你將需要使用命名的URL 模式。URL 的名稱使用的字符串可以包含任何你喜歡的字符。不只限制在合法的Python 名稱。
當命名你的URL 模式時,請確保使用的名稱不會與其它應用中名稱沖突。如果你的URL 模式叫做comment,而另外一個應用中也有一個同樣的名稱,當你在模板中使用這個名稱的時候不能保證將插入哪個URL。
在URL 名稱中加上一個前綴,比如應用的名稱,將減少沖突的可能。我們建議使用myapp-comment?而不是comment。
1|6命名空間模式
即使不同的APP使用相同的URL名稱,URL的命名空間模式也可以讓你唯一反轉命名的URL。
舉個例子:
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') ]?
現在,我的兩個app中 url名稱重復了,我反轉URL的時候就可以通過命名空間的名稱得到我當前的URL。
語法:
'命名空間名稱:URL名稱'
模板中使用:
{% url 'app01:detail' pk=12 pp=99 %}views中的函數中使用
v = reverse('app01:detail', kwargs={'pk':11})?
?這樣即使app中URL的命名相同,我也可以反轉得到正確的URL了。
轉載于:https://www.cnblogs.com/Ryan-Yuan/p/11537852.html
總結
以上是生活随笔為你收集整理的day53-Django之路由系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 星地融合→→→6G移动通信关键技术的未来
- 下一篇: 国科大高级人工智能8-归结原理和horn