URL 调度器

 

  为了给一个应用设计URL,你需要创建一个Python 模块,通常称为URLconf(URL configuration)。这个模块是纯粹的Python 代码,包含URL 模式(简单的正则表达式)到Python 函数(你的视图)的简单映射。

 

Django 如何处理一个URL请求

  1、Django 决定要使用的根URLconf 模块。通常,这个值就是Settings.py中的ROOT_URLCONF设置,

ROOT_URLCONF = 'MyHost.urls'

 

  2、Django 加载该Python 模块并寻找可用的urlpatterns它是django.conf.urls.url() 实例的一个Python 列表。

  3、Django 依次匹配每个URL 模式,在与请求的URL 匹配的第一个模式停下来。

  4、一旦其中的一个正则表达式匹配上,Django 将导入并调用给出的视图,它是一个简单的Python 函数(或者一个基于类的视图)。视图将获得如下参数:

    •   一个HttpRequest 实例。
    •   如果匹配的正则表达式返回了没有命名的组,那么正则表达式匹配的内容将作为位置参数提供给视图。
    •   关键字参数由正则表达式匹配的命名组组成,但是可以被django.conf.urls.url()的可选参数kwargs覆盖。

  5、如果没有匹配到正则表达式,或者如果过程中抛出一个异常,Django 将调用一个适当的错误处理视图。请参见下面的错误处理

 

URL命名分组

  下面是一个简单的 URLconf:

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/([0-9]{4})/$', views.year_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]

  上面的示例使用简单的、没有命名的正则表达式组(通过圆括号)来捕获URL 中的值并以 位置参数 传递给视图。在更高级的用法中,可以使用命名的正则表达式组来捕获URL  中的值并以 关键字参数 传递给视图。

 

  在Python 正则表达式中,命名正则表达式组的语法是(?P<name>pattern),其中name是组的名称,pattern 是要匹配的模式。

  下面是以上URLconf  使用命名组的重写:

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
]

 

指定视图参数的默认值

  有一个方便的小技巧是指定视图参数的默认值。 下面是一个URLconf 和视图的示例:

# URLconf
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^blog/$', views.page),
    url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
]

# View (in blog/views.py)
def page(request, num="1"):
    # Output the appropriate page of blog entries, according to num.
    ...

  在上面的例子中,两个URL模式指向同一个视图views.page —— 但是第一个模式不会从URL 中捕获任何值。如果第一个模式匹配,page() 函数将使用num参数的默认值"1"如果第二个模式匹配,page() 将使用正则表达式捕获的num 值。

 

包含其它的URLconfs

  在任何时候,你的urlpatterns 都可以包含其它URLconf 模块。这实际上将一部分URL 放置于其它URL 下面。

  例如,下面是 Django 网站自己的URLconf 中一个片段。它包含许多其它URLconf:

from django.conf.urls import include, url

urlpatterns = [
    # ... snip ...
    url(r'^community/', include('django_website.aggregator.urls')),
    url(r'^contact/', include('django_website.contact.urls')),
    # ... snip ...
]

  注意,这个例子中的正则表达式没有包含$(字符串结束匹配符),但是包含一个末尾的斜杠。

 

URL 的反向解析

from django.core.urlresolvers import reverse

   通常和redirect一起使用:

from django.shortcuts import redirect
from django.core.urlresolvers import reverse
class LogoutView(View):
def get(self, request):
logout(request)
return redirect(reverse("index"))

 

URL 命名空间

  因为一个应用的多个实例共享相同的命名URL,命名空间提供了一种区分这些命名URL 的方法。

###urls.py
from django.conf.urls import include, url

urlpatterns = [
    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 url
from . import views

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

 

posted @ 2017-05-26 21:40  Vincen_shen  阅读(277)  评论(0)    收藏  举报