django url

一个干净的,优雅的URL 方案是一个高质量Web 应用程序的重要细节。

这节我们来看看django是如何做到干净优雅的url的

1:Django如何处理一个请求

  1. 通过ROOT_URLCONF决定根URLCONF
  2. 调用所有的python模块找到urlpatterns(必须是一个列表)
  3. 按照顺序遍历url pattern,知道找到第一个匹配的项
  4. 如果找到,调用相应的view函数。。。
  5. 如果没找到,调用合适的错误处理函数

技术分享

简单的url示例

from django.conf.urls import patterns, url, include

urlpatterns = patterns(‘‘,
    (r^articles/2003/$, news.views.special_case_2003),
    (r^articles/(\d{4})/$, news.views.year_archive),
    (r^articles/(\d{4})/(\d{2})/$, news.views.month_archive),
    (r^articles/(\d{4})/(\d{2})/(\d+)/$, news.views.article_detail),
)
  • /articles/2003/03/03/会匹配最后一个 pattern. Django 会调用函数news.views.article_detail(request, ‘2003‘, ‘03‘, ‘03‘).
  • /articles/2005/3/ 一个也没有匹配上

命名组

格式为(?P<name>pattern)

示例如下

urlpatterns = patterns(‘‘,
    (r^articles/2003/$, news.views.special_case_2003),
    (r^articles/(?P<year>\d{4})/$, news.views.year_archive),
    (r^articles/(?P<year>\d{4})/(?P<month>\d{2})/$, news.views.month_archive),
    (r^articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$, news.views.article_detail),
)

 

这个示例和上面的示例是一样的功能,不过不同的地方是:上面的示例传的是位置参数,命名组的参数的关键字参数,这意味着你可以调整参数的位置

  • /articles/2005/03/ 会调用函数news.views.month_archive(request, year=‘2005‘, month=‘03‘), 而不是news.views.month_archive(request, ‘2005‘, ‘03‘).

事实上这不是很推荐的写法,不仅使得代码冗长,丑陋,事实上没这个必要,除非你确实想这么做

值得注意的是:

如果存在任何的命名组参数,那么非命名组参数将会被忽略;如果不存在命名组参数,所有的非命名组参数将按照顺序以位置参数的方式传进来

 url(regexviewkwargs=Nonename=Noneprefix=‘‘)

1:如果你有多个view函数的前缀一样,例如

urlpatterns = patterns(‘‘,
    (r^articles/(\d{4})/$, news.views.year_archive),
    (r^articles/(\d{4})/(\d{2})/$, news.views.month_archive),
    (r^articles/(\d{4})/(\d{2})/(\d+)/$, news.views.article_detail),
)

 

你可以这样写

urlpatterns = patterns(news.views,
    (r^articles/(\d{4})/$, year_archive),
    (r^articles/(\d{4})/(\d{2})/$, month_archive),
    (r^articles/(\d{4})/(\d{2})/(\d+)/$, article_detail),
)

 

2:如果你想引用其他的urlconf文件,你可以使用include这样写

urlpatterns = patterns(‘‘,
    # ... snip ...
    (r^comments/, include(django.contrib.comments.urls)),
    (r^community/, include(django_website.aggregator.urls)),
    (r^contact/, include(django_website.contact.urls)),
    (r^r/, include(django.conf.urls.shortcut)),
    # ... snip ...
)

3:如果你不想引用外部的urlconf,你还可以这样写

extra_patterns = patterns(‘‘,
    url(r^reports/(?P<id>\d+)/$, credit.views.report, name=credit-reports),
    url(r^charge/$, credit.views.charge, name=credit-charge),
)

urlpatterns = patterns(‘‘,
    url(r^$, apps.main.views.homepage, name=site-homepage),
    (r^help/, include(apps.help.urls)),
    (r^credit/, include(extra_patterns)),
)

 

4:当你给include配置额外参数的时候,这个额外参数会被附加到被include的urlconf文件的每一条url pattern里面

#Set one:
# main.py
urlpatterns = patterns(‘‘,
    (r^blog/, include(inner), {blogid: 3}),
)
# inner.py
urlpatterns = patterns(‘‘,
    (r^archive/$, mysite.views.archive),
    (r^about/$, mysite.views.about),
)
#Set two:
# main.py
urlpatterns = patterns(‘‘,
    (r^blog/, include(inner)),
)
# inner.py
urlpatterns = patterns(‘‘,
    (r^archive/$, mysite.views.archive, {blogid: 3}),
    (r^about/$, mysite.views.about, {blogid: 3}),
)

 

这两个set是一样的意思

5:如果两个url pattern被同一个view函数处理,那么当在模板中使用url指令的时候就会发生冲突,这时候url的name参数就可以派上用场了

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 %}

 

需要注意的是,保证你使用的name参数在整个项目里面是唯一的,否则还是有可能发生冲突的

 

 

 

 

 

 

p

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。