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

Django url()函式詳解

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的時候可能會遇到一個問題就是:對於:

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

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

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

在模版中可以使用:

{% url arch-summary 1945 %}
{% 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'%},否則:
    NoReverseMatch at /
    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


關注公眾號「Python之禪」(id:vttalk)獲取最新文章 python之禪

猜你喜歡