Django url()函數詳解
url()函數看起來的格式象:url(r^/account/$‘, views.index, name=index)
,它可以接收四個參數,分別是兩個必選參數:regex
、view
和兩個可選參數:kwargs
、name
,接下來詳細介紹這四個參數。
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):
註意:
- 如果在url.py中有
url(r‘^comment/(\d{1,9})/delete/$‘,‘delete_comment‘),
的配置,如果不存在delete_comment
這樣一個函數視圖,如果在模版中使用了{% url path.to.some_view %}
這個標簽,那麽拋出 ViewDoesNotExit錯誤。仔細想想很有道理,如果視圖不存在,即使匹配到了URL,當訪問這個URL的時候,還是會拋ViewDoesNotExit的異常,這裏Django只是在加載解析URLConf的時候就做了檢查。 - 如果在根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()函數詳解