1. 程式人生 > >Django url()函數詳解

Django url()函數詳解

cout emp stack del keyword rst http index 一模一樣

url()函數看起來的格式象:url(r^/account/$‘, views.index, name=index),它可以接收四個參數,分別是兩個必選參數:regexview和兩個可選參數:kwargsname,接下來詳細介紹這四個參數。

regex

regex代表一個正則表達式,凡是與regex匹配的URL請求都會執行到url()函數中對應的第二個參數view代表的視圖函數中。需要註意的是:正則表達式不會匹配URL中的域名和查詢參數,如:http://www.foofish.net/article/?page=3, Django只找article/。正則表達式在URLconf模塊加載時就編譯好了,所以在匹配的時候速度是很快的。

view

Django匹配正則表達式成功後,就會找到相應的視圖函數,Django始終用HttpRequest對象作為第一個參數傳遞給視圖函數,此外使用regex參數中攜帶的參數作為可選參數傳遞給視圖函數。如:url(r‘^(?P<article_id>\d+)/$‘, views.detail, name=‘detail‘),,括號對(?P<article_id>\d+)裏面的參數將作為第二個參數傳遞給視圖函數detail(request, article_id),這裏參數的名字必須一模一樣。因為你在url函數中顯示的指定了該參數的名字,當然你也可以不顯示的指定,如:url(r‘^(\d+)/$‘, views.detail, name=‘detail‘)

,這樣在視圖函數裏,第二個參數的名稱就隨便命名了。它根據位置參數的位置來匹配。

name
講name之前,先說說Django template的內建標簽url,{% url path.to.some_view%}可以返回視圖函數對應的URL(相對域名的絕對路徑),比如url(r^/account/$‘, views.index, name=index),使用{% url view.index %}將返回/accout/,這樣做可以提高模版的靈活性,如果是使用硬編碼的方式,模版難以維護。

使用標簽url的時候可能會遇到一個問題就是:對於:

1 urlpatterns = patterns(‘‘,
2     url(r
^archive/(\d{4})/$, archive, name="full-archive"), 3 url(r^archive-summary/(\d{4})/$, archive, {summary: True}, "arch-summary"), 4 )

同一個視圖函數有多個urlconf,此時模版系統想通過視圖名archive獲取URL時,就不知所措了,name參數就是用來解決此問題的。name用來唯一區一個視圖對應多個urlconf的場景。通過name來反向獲取URL。
如:

1 urlpatterns = patterns(‘‘,
2     url(r^archive/(\d{4})/$, archive, name="full-archive"),
3     url(r^archive-summary/(\d{4})/$, archive, {summary: True}, "arch-summary"),
4 )

在模版中可以使用:

1 {% url arch-summary 1945 %}

2 {% url full-archive 2007 %}

kwargs

kwargs就是一個字典類型的參數,它的使用方式如:

url(r^archive-summary/(\d{4})/$, archive, {summary: True}, "arch-summary"),

這裏的kwargs 就是 {‘summary‘: True}

視圖函數中就是這樣使用:

def archive(request, archive_id, summary):

註意:

  1. 如果在url.py中有url(r‘^comment/(\d{1,9})/delete/$‘,‘delete_comment‘),的配置,如果不存在delete_comment這樣一個函數視圖,如果在模版中使用了{% url path.to.some_view %}這個標簽,那麽拋出 ViewDoesNotExit錯誤。仔細想想很有道理,如果視圖不存在,即使匹配到了URL,當訪問這個URL的時候,還是會拋ViewDoesNotExit的異常,這裏Django只是在加載解析URLConf的時候就做了檢查。
  2. 如果在根url.py文件中使用了url(r‘^people/‘, include(‘people.urls‘, namespace=‘people‘)),這裏people是一個app,那麽在people這個app中的url.py中url(r‘^(\d{1,9})/$‘,‘index‘, name=‘index‘)必須指定了name=index才能正常使用{% url ‘people:index‘%},否則:
    1 NoReverseMatch at /
    2 Reverse for subjects with arguments () and keyword arguments {} not found

    當然如果你確定不是上述問題拋出的此異常,那麽可以看下這兩個答案:
    http://stackoverflow.com/questions/9649587/reverse-for-with-arguments-and-keyword-arguments-not-found
    http://stackoverflow.com/questions/14882491/django-release-1-5-url-requires-a-non-empty-first-argument-the-syntax-change
    本文參考
    https://docs.djangoproject.com/en/1.1/topics/http/urls/#id2
    https://docs.djangoproject.com/en/1.1/ref/templates/builtins/#std:templatetag-url

Django url()函數詳解