Django路由层详解

Django中路由的作用

URL配置(URLconf)就是Django 所支撑的网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代码对应执行

典型例子:

from django.conf.urls import url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
]

路由的基本使用

from django.conf.urls import url
from django.contrib import admin

urlpatterns = [
	url(正则表达式, views视图函数,参数,别名),
]
  • 正则表达式:一个正则表达式字符串
  • views视图函数:一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
  • 参数:可选的要传递给视图函数的默认参数(字典形式)
  • 别名:一个可选的name参数
注意:
  • 若要从URL 中捕获一个值,只需要在它周围放置一对圆括号。
  • 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
  • 每个正则表达式前面的’r’ 是可选的但是建议加上。它告诉Python 这个字符串是“原始的”
  • urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续
APPEND_SLASH

Django settings.py配置文件中默认没有 APPEND_SLASH 这个参数,但 Django 默认这个参数为 APPEND_SLASH = True。 其作用就是自动在网址结尾加’/’。

其效果就是:

我们定义了urls.py

from django.conf.urls import url
from app01 import views

urlpatterns = [
	url(r'^blog/$', views.blog),
]

访问 http://www.example.com/blog 时,默认将网址自动转换为 http://www.example/com/blog/

如果在settings.py中设置了 APPEND_SLASH=False,此时我们再请求 http://www.example.com/blog 时不再向后面自动添加/,就会提示找不到页面。

路由的分组

无名分组

# 路由层
from django.conf.urls import url
from app01 import views

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

# 视图层
def year_archive(request, year):
	'''
	year: 接收路由层传递过来的参数
	'''
	return HttpResponse('当前是%s年' % year)

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

无名分组分出几个值,视图函数就要接受几个值(位置参数形式传过来的)

有名分组

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

按照有名分组,上面的示例应该这样写:

from django.conf.urls import url
from app01 import views

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

有名分组与无名分组在使用上没有太大差别,只是有名分组对应的视图函数的形参名字必须和分组名保持一致,也就是说,有名分组会把分出来的参数按照关键字参数传递给视图函数,所以一定要保持名字上的一致

在实际应用中,这意味你的URLconf 会更加明晰且不容易产生参数顺序问题的错误 —— 你可以在你的视图函数定义中重新安排参数的顺序。当然,这些好处是以简洁为代价。

注意:有名分组和无名分组不能混合使用

路由分发

一个Django项目里面有多个app时,不同app的视图层可能会有名字相同的视图函数,为了避免名称冲突,我们通过路由分发的方式在总路由中进行分发,使每个app在自身内部进行路由的配置

# 导入include
from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # 匹配顺序:匹配app01成功则相应include函数,去到app01文件夹下的urls文件中继续匹配后续路由
    url(r'^app01/', include('app01.urls')),
	url(r'^app02/', include('app02.urls'))
]
# app01中的urls文件内容
from app01 import views

urlpatterns = [
	url(r'^test/', views.test),
]

如果浏览器输入app01/test/,就会响应到app01下views中的test取执行

反向解析(了解)

在视图函数中重定向的地址如果是写死的,url地址变更时,需要所有的url都进行修改,比较麻烦,我们可以通过反向解析,动态获取url的地址

# 路由层
from django.conf.urls import url
from app01 import views

urlpatterns = [
	url(r'^admin/', admin.site.urls),
	url(r'^test/$', views.test, name='test')
]
# 视图层
from django.shortcuts import reverse

def re_url():
	url=reverse('test(url地址的别名)')
	# 如果做了分组(意味着需要接受参数)
	url=reverse('test(url地址的别名)',args=[],kwargs={})
	return redirect(url)
{# django模板层 #}
{% url 'url地址的别名'%}
# 如果做了分组(意味着需要接受参数)
{% url 'url地址的别名' 参数1 参数2 ... 参数n %}

这样,即使路由层中的路由更改了,我们也可以不用修改视图层或模板层的路由地址,即便我们不应该去修改路由层中的路由。

名称空间

路由分发时,可以指定名称空间:

# 导入include
from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^app01/', include('app01.urls', namespace='app01')),
	url(r'^app02/', include('app02.urls', namespace='app02'))
]

名称空间可以在视图层进行反向解析使用
不建议使用名称空间

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章