Django URL name詳解

咱們基於上一節的代碼來開始這一節的內容。

上節源代碼:zqxt_views(django 1.4 - django 1.10).zip [更新於 2016-09-06 00:13:23]css

1. 打開 zqxt_views/urls.pyhtml

1
2
3
4
5
6
7
8
9
10
from  django.conf.urls  import  url
from  django.contrib  import  admin
from  calc  import  views as calc_views
 
 
urlpatterns  =  [
     url(r '^add/$' , calc_views.add, name = 'add' ),
     url(r '^add/(\d+)/(\d+)/$' , calc_views.add2, name = 'add2' ),
     url(r '^admin/' , admin.site.urls),
]


url(r'^add/$', calc_views.add, name='add'), 這裏的 name='add' 是用來幹什麼的呢?python

爲了弄清這個問題,咱們先建一個首頁的視圖和url
web


2. 修改 calc/views.py正則表達式

1
2
3
4
5
6
7
8
9
from  django.http  import  HttpResponse
from  django.shortcuts  import  render
 
 
def  index(request):
     return  render(request,  'home.html' )
 
 
...此處省去一些代碼

render 是渲染模板,不懂先照着打就好。shell


3. 將 'calc' 這個 app 加入到 zqxt_views/settings.py 中django

1
2
3
4
5
6
7
8
9
10
INSTALLED_APPS  =  [
     'django.contrib.admin' ,
     'django.contrib.auth' ,
     'django.contrib.contenttypes' ,
     'django.contrib.sessions' ,
     'django.contrib.messages' ,
     'django.contrib.staticfiles' ,
 
     'calc' ,
]

這樣,使用render的時候,Django 會自動找到 INSTALLED_APPS 中列出的各個 app 下的 templates 中的文件。bash

小提示,DEBUG=True 的時候,Django 還能夠自動找到 各 app 下 static 文件夾中的靜態文件(js,css,圖片等資源),方便開發哦,後面有專門的章節會講這些。服務器


4. 咱們在 calc 這個 app 中新建一個 templates 文件夾,在templates中新建一個 home.html (關於模板更詳細的能夠稍後看下一節)session

文件 calc/templates/home.html 中寫入如下內容

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
< html >
< head >
     < title >自強學堂</ title >
</ head >
< body >
 
< a  href = "/add/4/5/" >計算 4+5</ a >
 
</ body >
</ html >


修改 zqxt_views/urls.py

1
2
3
4
5
6
7
8
...此處省去一些代碼
 
urlpatterns  =  [
     url(r '^$' , calc_views.index, name = 'home' ),
     url(r '^add/$' , calc_views.add, name = 'add' ),
     url(r '^add/(\d+)/(\d+)/$' , calc_views.add2, name = 'add2' ),
     url(r '^admin/' , admin.site.urls),
]

運行開發服務器,咱們訪問 http://127.0.0.1:8000/ 能夠看到


django-url-name-1.png

咱們計算加法的時候用的是 /add/4/5/ ,後來需求發生變化,好比咱們又想改爲 /4_add_5/這樣的格式,可是咱們在網頁中,代碼中不少地方都寫死的是 

1
< a  href = "/add/4/5/" >計算 4+5</ a >

這樣就致使當咱們改了 urls.py 後,對應的模板,甚至還視圖中的跳轉,以及 models.py 中也可能有獲取網址的地方。

每一個地方都要改,修改的代價很大,一不當心,有的地方沒改過來,那個就不能用了


那麼有沒有更優雅的方式來解決這個問題呢?固然答案是確定的。

咱們先說一下如何用 Python 代碼獲取對應的網址(能夠用在 views.py,models.py等各類須要轉換獲得網址的地方):

咱們在終端上輸入(推薦安裝 bpython, 這樣Django會用 bpython的 shell)

1
python manage.py shell

1
2
3
4
5
>>>  from  django.core.urlresolvers  import  reverse
>>> reverse( 'add2' , args = ( 4 , 5 ))
u '/add/4/5/'
>>> reverse( 'add2' , args = ( 444 , 555 ))
u '/add/444/555/'

reverse 接收 url 中的 name 做爲第一個參數,咱們在代碼中就能夠經過 reverse() 來獲取對應的網址(這個網址能夠用來跳轉,也能夠用來計算相關頁面的地址),只要對應的 url 的name不改,就不用改代碼中的網址。

在網頁模板中也是同樣,能夠很方便的使用。

1
2
3
4
5
6
7
不帶參數的:
{% url 'name' %}
帶參數的:參數能夠是變量名
{% url 'name' 參數 %}
 
例如:
< a  href = "{% url 'add2' 4 5 %}" >link</ a >

上面的代碼渲染成最終的頁面是

1
< a  href = "/add/4/5/" >link</ a >

這樣就能夠經過 {% url 'add2' 4 5 %} 獲取到對應的網址 /add/4/5/


當 urls.py 進行更改,前提是不改 name(這個參數設定好後不要輕易改),獲取的網址也會動態地跟着變,好比改爲:

1
url(r '^new_add/(\d+)/(\d+)/$' , calc_views.add2, name = 'add2' ),


注意看重點 add 變成了 new_add,可是後面的 name='add2' 沒改,這時 {% url 'add2' 4 5 %} 就會渲染對應的網址成 /new_add/4/5/

reverse 函數也是同樣,獲取的時候會跟着變成新的網址,這樣,在想改網址時只須要改 urls.py 中的正則表達式(url 參數第一部分),其它地方都「自動」跟着變了,是否是這樣更好呢?


另外,好比用戶收藏夾中收藏的URL是舊的,如何讓之前的 /add/3/4/自動跳轉到如今新的網址呢?

要知道Django不會幫你作這個,這個須要本身來寫一個跳轉方法

具體思路是,在 views.py 寫一個跳轉的函數:

1
2
3
4
5
6
7
8
from  django.http  import  HttpResponseRedirect
from  django.core.urlresolvers  import  reverse
 
 
def  old_add2_redirect(request, a, b):
     return  HttpResponseRedirect(
         reverse( 'add2' , args = (a, b))
     )

urls.py中:

1
2
     url(r '^add/(\d+)/(\d+)/$' , calc_views.old_add2_redirect),
     url(r '^new_add/(\d+)/(\d+)/$' , calc_views.add2, name = 'add2' ),

這樣,假如用戶收藏夾中有 /add/4/5/ ,訪問時就會自動跳轉到新的 /new_add/4/5/ 了


開始可能以爲直接寫網址簡單,可是用多了你必定會發現,用「死網址」的方法很糟糕。

相關文章
相關標籤/搜索