Django的url配置相同遵循着DRY(dont repeat yourself)的规则。下面都是官方文档的样例:

首先介绍的是Django怎样处理http的请求:

1、在setting里定义ROOT_URLCONF
,这个值就是url的根配置,但若被request processing中间件定义了HttpRequest的urlconf属性,会替换掉ROOT_URLCONF


2、Django 载入模块。寻找 urlpatterns。它是pattern函数的返回值。是url的list

3、寻找每一个url pattern 直到找到第一个匹配的

4、一旦找到,会调用相应的view函数。

view函数必须带有HttpRequest对象(request),若url里没有命名參数,view函数里能够带位置參数,若有命名參数,则view函数里相同有命名參数。同一时候命名參数还有可能是 django.conf.urls.url()函数里加入的额外keyword參数。

5、若给出的url没有pattern匹配,则触发异常。

如:

from django.conf.urls import patterns, url

from . import views

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

注意article前不用加 /

括号的作用是捕捉传入url的值给view函数。

最后一个若请求的url是 articles/2003/03/03,调用的view 函数为views.article_detail(request, '2003', '03', '03').

在正则里分组:

url(r'^articles/(?

P<year>\d{4})/(?

P<month>\d{2})/(?P<day>\d{2})/$', views.article_detail)

则相同的url请求调用的是views.article_detail(request, year='2003', month='03', day='03').

django 不会处理传入的域名和查询參数,比方http://www.example.com/myapp/?page=3 仅仅能匹配myapp/

捕捉到的传给view函数的值永远是string类型的。要变成数字则须要转换。

可将不同的url指向同一个view函数。如

    url(r'^blog/$', views.page),
url(r'^blog/page(?P<num>\d+)/$', views.page),

page函数能够有个默认的參数 num=1 。

性能:每一个正则会在第一次被訪问的时候被编译。所以速度非常快。

错误处理:若不能匹配不论什么一个正则,或有异常,django会调用错误处理的view函数。

须要在ROOT_URLCONF里指定。其它位置无效。

包含

传递string取代view函数:

    url(r'^archive/$', 'mysite.views.archive'),
url(r'^about/$', 'mysite.views.about'),
url(r'^contact/$', 'mysite.views.contact'),

有同样的前缀还能够把同样的前缀写到patterns的第一个參数里:

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

多个前缀时能够用urlpatterns+=patterns(...) ,记住url配置也是python代码。

include的使用方法,常见使用方法:

from django.conf.urls import include, patterns, url
...
url(r'^comments/', include('django.contrib.comments.urls')),
url(r'^community/', include('django_website.aggregator.urls')),
url(r'^contact/', include('django_website.contact.urls')),
...

include的还有一种使用方法,參数是patterns函数的返回值:

extra_patterns = patterns('',
url(r'^reports/(? P<id>\d+)/$', credit_views.report),
url(r'^charge/$', credit_views.charge),
)
<pre name="code" class="python">urlpatterns = patterns('',
url(r'^$', main_views.homepage),
url(r'^help/', include('apps.help.urls')),
url(r'^credit/', include(extra_patterns)),
)


url传递的命名參数,位置參数在include里相同有效。

给view函数传递额外參数,在url函数里能够传递一个字典。

    url(r'^blog/(?P<year>\d{4})/$', views.year_archive, {'foo': 'bar'}),

django会调用 views.year_archive(request, year='2005', foo='bar').

若有同名冲突,即正则分组的名和字典里key的值同样,则取后者。

url反射:

反向获取视图相应的url是个常见的需求。硬编码(把url写死)不是DRY的做法。django在MTV各层分别提供了工具来反射获取url。

模板中: url 模板标签

python代码中。用django.core.urlresolvers.reverse()函数

模型层: get_absolute_url()方法

比如有

url(r'^articles/(\d{4})/$', views.year_archive),

的相应关系。

<a href="{% url 'news.views.year_archive' 2012 %}">2012 Archive</a>
{# Or with the year in a template context variable: #}
<ul>
{% for yearvar in year_list %}
<li><a href="{% url 'news.views.year_archive' yearvar %}">{{ yearvar }} Archive</a></li>
{% endfor %}
</ul>

在python代码中:

year = 2006
return HttpResponseRedirect(reverse('news.views.year_archive', args=(year,)))####參数是tuple

这样当url改变时仅仅改变入口就可以。

命名urlpatterns

存在多个url相应同一个view的情况。这样当反射的时候会出现歧义。解决的方法是在定义使用url函数时加上 name=參数。

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

{% url 'arch-summary' 1945 %}
{% url 'full-archive' 2007 %}

就分别相应了不同的url。

url命名空间:

url命名空间同意惟一地反射已命名的url,即使不同的app有同样的url名字。

第三方app使用命名空间是非常好的习惯。类似地。若一个应用的多个实例部署时,也同意你反射url,由于一个app的多个实例共享同样的url,命名空间提供了一种方法来区分它们。

充分利用了url命名空间的django应用可被特定网站部署多次。比如admin的AdminSite类同意你部署一个admin的多个实例。

url namespace有两部分,各自是application namespace和instance namespace。用冒号分分隔。namespace能够嵌套, 'sports:polls:index'

命名空间url的反射:e.g. 'polls:index'

1、django把命名空间分开,找application namespace,本例为polls。

这会产生一个polls 的实例的列表

2、若定义了current application(的实例)。 django找到并返回这个实例的url 解析。current application被设定为模板上下文的一个属性,期望有多部署的应用应该设定current_app 属性给每一个渲染模板的Context或者RequestContext。

3、若无current application,django寻找默认的应用实例,默认的应用实例是有和application namespace同样名称的instance namespace。本例中是polls:polls

4、若没有默认实例,django会跳出最后一次部署的应用实例,无论其instance namespace是什么。

5、若提供的namespace和第一步的application namespace不匹配。django尝试直接寻找这个namespace作为instance namespace。

如:两个polls应用的实例。一个叫author-polls。还有一个叫publisher-polls。

urls.py

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

urlpatterns = patterns('',
url(r'^author-polls/', include('polls.urls', namespace='author-polls', app_name='polls')),
url(r'^publisher-polls/', include('polls.urls', namespace='publisher-polls', app_name='polls')),
)

polls/urls.py

from django.conf.urls import patterns, url

from . import views

urlpatterns = patterns('',
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
...
)

1、若一个实例是当前实例,即。若准备在实例‘'author-polls中渲染datail page,'polls:index'会解析到'author-polls实例。也即以下的样例会返回"/author-polls/"

reverse('polls:index', current_app=self.request.resolver_match.namespace)
{% url 'polls:index' %}

要注意current_app属性要被加到context里,

def render_to_response(self, context, **response_kwargs):
response_kwargs['current_app'] = self.request.resolver_match.namespace
return super(DetailView, self).render_to_response(context, **response_kwargs)

2、若无当前实例,即要渲染的页面在网站上的其它页面, 'polls:index'会解析到最后一个注冊给polls的实例。

由于没有默认的(instance namespace of 'polls')。会被解析到 'publisher-polls'

3、'author-polls:index'会一直被解到实例为 'author-polls'的索引页,还有一个也一样。

若有polls的默认实例。即实例名为polls。则上面改变的地方在第2步,会被解析为默认的实例而不是最后一个注冊的。

url命名空间和 include

两种方法

1、显式指明 application 和instance 的namespace,作为include的參数

url(r'^polls/', include('polls.urls', namespace='author-polls', app_name='polls')),

定义在polls里面的url都被增加了app_name 为 polls和instance为 author-polls的命名空间

2、include能够接受一个tuple作为參数,tuple是三元的,各自是

(<patterns object>, <application namespace>, <instance namespace>)

from . import views

polls_patterns = patterns('',
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
) url(r'^polls/', include((polls_patterns, 'polls', 'author-polls'))),

记得一定要传tuple。若只传送的是三个元素。则会与第一种效果一样。

可是instance 和application namespace的顺序。两种签名是相反的。django不会报错

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

最后附上 include url patterns的源代码

from importlib import import_module

from django.core.urlresolvers import (RegexURLPattern,
RegexURLResolver, LocaleRegexURLResolver)
from django.core.exceptions import ImproperlyConfigured
from django.utils import six __all__ = ['handler400', 'handler403', 'handler404', 'handler500', 'include', 'patterns', 'url'] handler400 = 'django.views.defaults.bad_request'
handler403 = 'django.views.defaults.permission_denied'
handler404 = 'django.views.defaults.page_not_found'
handler500 = 'django.views.defaults.server_error'
[docs]def include(arg, namespace=None, app_name=None):
if isinstance(arg, tuple):
# callable returning a namespace hint
if namespace:
raise ImproperlyConfigured('Cannot override the namespace for a dynamic module that provides a namespace')
urlconf_module, app_name, namespace = arg
else:
# No namespace hint - use manually provided namespace
urlconf_module = arg if isinstance(urlconf_module, six.string_types):
urlconf_module = import_module(urlconf_module)
patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module) # Make sure we can iterate through the patterns (without this, some
# testcases will break).
if isinstance(patterns, (list, tuple)):
for url_pattern in patterns:
# Test if the LocaleRegexURLResolver is used within the include;
# this should throw an error since this is not allowed!
if isinstance(url_pattern, LocaleRegexURLResolver):
raise ImproperlyConfigured(
'Using i18n_patterns in an included URLconf is not allowed.') return (urlconf_module, app_name, namespace)
[docs]def patterns(prefix, *args):
pattern_list = []
for t in args:
if isinstance(t, (list, tuple)):
t = url(prefix=prefix, *t)
elif isinstance(t, RegexURLPattern):
t.add_prefix(prefix)
pattern_list.append(t)
return pattern_list
[docs]def url(regex, view, kwargs=None, name=None, prefix=''):
if isinstance(view, (list, tuple)):
# For include(...) processing.
urlconf_module, app_name, namespace = view
return RegexURLResolver(regex, urlconf_module, kwargs, app_name=app_name, namespace=namespace)
else:
if isinstance(view, six.string_types):
if not view:
raise ImproperlyConfigured('Empty URL pattern view name not permitted (for pattern %r)' % regex)
if prefix:
view = prefix + '.' + view
return RegexURLPattern(regex, view, kwargs, name)

django url调度的更多相关文章

  1. Django URL调度器

    Django处理请求的流程 Django确定要使用的根URLconf模块.通常,这是ROOT_URLCONF设置的值,但如果传入 HttpRequest对象具有urlconf 属性(由中间件设置),则 ...

  2. Django 源码小剖: 更高效的 URL 调度器(URL dispatcher)

    效率问题 django 内部的 url 调度机制说白了就是给一张有关匹配信息的表, 这张表中有着 url -> action 的映射, 当请求到来的时候, 一个一个(遍历)去匹配. 中, 则调用 ...

  3. Django 源码小剖: URL 调度器(URL dispatcher)

    在刚开始接触 django 的时候, 我们尝试着从各种入门文档中创建一个自己的 django 项目, 需要在 mysite.urls.py 中配置 URL. 这是 django url 匹配处理机制的 ...

  4. URL 调度器(URL dispatcher)

    URL 调度器(URL dispatcher) 在刚开始接触 django 的时候, 我们尝试着从各种入门文档中创建一个自己的 django 项目, 需要在 mysite.urls.py 中配置 UR ...

  5. Django Url编码问题

    Django Url编码问题   最近在学习Django,写一个blog程序练练手手.对于一个才开始接触web开发的来说,难免会遇到一些问题.   有一个这样的模板: {%for k,v in cat ...

  6. Django URL(路由系统)

    Django URL Django 1.11版本 URLconf官方文档 URL配置(URLconf)就像 Django 所支撑网站的目录.它的本质是URL模式以及要为该URL模式调用的视图函数之间的 ...

  7. python :Django url /views /Template 文件介绍

    1,Django URL 路由系统 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表:你就是以这种方式告诉Django ...

  8. 第五篇Django URL name 详解

    Django URL name 详解 利用Django开发网站,可以设计出非常优美的url规则,如果url的匹配规则(包含正则表达式)组织得比较好,view的结构就会比较清晰,比较容易维护. Djan ...

  9. Django的URL调度

    1.URLconf (URL configuration):(Django版本1.11.20,其它版本可能各有差异.) 在Django中Python后端与前端URL进行交互,是通过一个名为urlcon ...

随机推荐

  1. PS图片

    第二次练习PS,不知道找什么图片,就这么做着吧.然后自己学习了下动画制作,但是中间有些问题,需要再研究研究. 像 CS6中新建蒙版文档,画出的图形单位是厘米,怎么改为像素?(答案看后续博客....)

  2. opencv鼠标绘制直线 C++版

    因为需要在图片上标记直线,所以从网上找了相应的参考资料.但大多都是c风格的,于是自己就写了一个c++风格的. opencv2.4.11,win8.1,vs2013 #include <cv.h& ...

  3. 什么是C# Lambda表达式?形如:p=>p.abc

    这里介绍C# Lambda表达式,它实际上和匿名方法没有什么不同.Lambda的输入参数就对应着delegate括号里面的参数,由于C# Lambda表达式可以推断参数的类型,所以这里的参数无需声明. ...

  4. File 操纵目录

    mkdir()   创建目录 不可及联创建    即父路径中一旦有不存在文件夹  即创建失败 mkdirs() 创建目录,及联创建 list() 列出目录内所包含的文件名(string) listFi ...

  5. 转:onConfigurationChanged的作用

    API原文说明:android:configChangesLists configuration changes that the activity will handle itself. When ...

  6. C#中ref参数及out参数对比

    ref 关键字和out关键字均会导致参数通过引用来传递(相同点1).这是两者的共同点. 通过引用传递参数,会使方法中对参数所做的任何修改都将反映在该变量中. 两者还有一个共同点,那就是:若要使用 re ...

  7. android的四种加载模式

    在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. An ...

  8. WM_PAINT消息详解,使用InvalidateRect或InvalidateRgn函数刻意产生WM_PAINT消息(WIN7里有变化,“调整视觉效果”,将“启用桌面组合”去掉)

    什么时候会触发WM_PAINT消息消息呢? 以下内容来自大名鼎鼎的<Windows程序设计(第五版)> 大多数Windows程序在WinMain中进入消息循环之前的初始化期间都要呼叫函数U ...

  9. 纯CSS设置Checkbox复选框控件的样式

    Checkbox复选框是一个可能每一个网站都在使用的HTML元素,但大多数人并不给它们设置样式,所以在绝大多数网站它们看起来是一样的.为什么不把你的网站中的Checkbox设置一个与众不同的样式,甚至 ...

  10. 挺苹果的声音,iPhone 5s的两处进步

    苹果iPhone 5s发布后的两处重大进步让我很关注,但看了网上众多网友的点评,又深深的被中国当前手机发烧友圈的这种屌丝文化所震撼,这不是一条正确的道路,这将把中国的手机产业引向歧途,所以我不得不说几 ...