Django框架----命名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 reverse

reverse("index", args=("2018", ))

 

例子:

考慮下面的URLconf:

from django.conf.urls import url

from . import views

urlpatterns = [
    #...
    url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'),
    #...
]

根據這里的設計,某一年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.core.urlresolvers import reverse
from django.http import HttpResponseRedirect

def redirect_to_year(request):
    # ...
    year = 2006
    # ...
    return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))

如果出於某種原因決定按年歸檔文章發布的URL應該調整一下,那么你將只需要修改URLconf 中的內容。

在某些場景中,一個視圖是通用的,所以在URL 和視圖之間存在多對一的關系。對於這些情況,當反查URL 時,只有視圖的名字還不夠。

 

例子中:

分析:想我們一開始寫的硬編碼,也就是吧action要跳轉的路徑寫死了。但是像淘寶,天貓等都會經常更新新東西,,那么你的頁面上的url路徑也會時不時的變化。但是如果有特別多的商品,那么你就得去服務端一個一個的改,這樣顯得很麻煩,那么有沒有一種機制幫我們解決問題呢?那就按照我下面的辦法解決。就把url路徑寫活了。

1、首先給url起一個別名。

2、然后在login.html中寫上{%  url ‘別名’’  %}    ,如果在頁面中點擊查看元素,它會變成login.html,,,當然我的是分發了,,就會變成test/login.html

3、這樣你就可以修改你的正則了,,因為他是按照別名走的,不會影響。

urls.py

login.html

查看元素的結果:

 

 這樣的好處是:無論你怎么改你要匹配的url,只要你寫上了別名。在html實現了模板語法,就會去找別名對應的那個url,以后不管你怎么改url都沒事,就寫活了,就不像一開始寫的硬編碼了。

 

注意:

 

為了完成上面例子中的URL 反查,你將需要使用命名的URL 模式。URL 的名稱使用的字符串可以包含任何你喜歡的字符。不只限制在合法的Python 名稱。

 

當命名你的URL 模式時,請確保使用的名稱不會與其它應用中名稱沖突。如果你的URL 模式叫做comment,而另外一個應用中也有一個同樣的名稱,當你在模板中使用這個名稱的時候不能保證將插入哪個URL。

 

在URL 名稱中加上一個前綴,比如應用的名稱,將減少沖突的可能。我們建議使用myapp-comment 而不是comment

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM