Django-路由(URLconf)
简单的路由配置
1.顶层的URL分发器
在setting中设置了顶层的url分发器的配置,所有请求路由进来都会到该文件中匹配对应的路由条目和分配指定的视图函数。
ROOT_URLCONF = 'Django_Base.urls'
URL配置(URLconf)就像Django所支撑网站的目录。它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表关系。URL的加载是从配置文件中开始的。
2.url配置示例
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), ]
urlpatterns = [
url(正则表达式, view函数, 参数, 别名,前缀)
]
参数说明:
- 一个正则表达式字符串。
- 一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串。
- 可选的要传递给视图函数的默认参数(字典形式)。
- 一个可选的name参数:接合模板方便管理
- 路径前缀:这是app的前缀
注意事项:
- 若要从URL 中捕获一个值,只需要在它周围放置一对圆括号。
- 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是
^articles而不是^/articles。 - 每个正则表达式前面的'r' 是可选的但是建议加上。它告诉Python 这个字符串是“原始的” —— 字符串中任何字符都不应该转义
有名分组URL
上面的示例使用简单的、没有命名的正则表达式组(通过圆括号)来捕获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), ]
这个实现与前面的示例完全相同,只有一个细微的差别:捕获的值作为关键字参数而不是位置参数传递给视图函数。例如:
''' /articles/2005/03/ 请求将调用views.month_archive(request, year='2005', month='03')函数,而不是views.month_archive(request, '2005', '03')。 /articles/2003/03/03/ 请求将调用函数views.article_detail(request, year='2003', month='03', day='03')。 '''
URL分解器,include函数
通常一个 URL 分解器对应一个 URL 配置模块,它可以包含多个URL模式,也可以包含多个其他URL分解器。通过这种包含结构设计,实现Django对URL的层级解析。
URL 分解器是 Django 实现 app 与项目解耦的关键。通常由 include 方法操作的 URL 配置模块,最终会被解释成为 URL 分解器。
顶层url分发器
from django.conf.urls import url, include urlpatterns = [ url(r'^app01', include('app01.urls')) ]
app01.urls
# app01.urls from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^$', views.index), url(r'timer/$', views.timer), url(r'login/$', views.login), url(r'index/$', views.index), url(r'articles/2003/$', views.special_case_2003), # 无名分组 url(r'articles/(\d{4})/$', views.article_year), # 有名分组 url(r'articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$', views.article_date), ]
反向解析
在使用Django 项目时,一个常见的需求是获得URL 的最终形式,以用于嵌入到生成的内容中(视图中和显示给用户的URL等)或者用于处理服务器端的导航(重定向等)。人们强烈希望不要硬编码这些URL(费力、不可扩展且容易产生错误)或者设计一种与URLconf 毫不相关的专门的URL 生成机制,因为这样容易导致一定程度上产生过期的URL。
在需要URL 的地方,对于不同层级,Django 提供不同的工具用于URL 反查:
- 在模板中:使用url 模板标签。
- 在Python 代码中:使用
django.core.urlresolvers.reverse()函数。
urls.py
from django.conf.urls import url from . import views urlpatterns = [ #... url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'), #... ]
模版中:
<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a> <ul> {% for yearvar in year_list %} <li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li> {% endfor %} </ul>
python中:
from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect def redirect_to_year(request): # ... year = 2006 # ... return HttpResponseRedirect(reverse('news-year-archive', args=(year,))) # 同redirect("/path/")
当命名你的URL 模式时,请确保使用的名称不会与其它应用中名称冲突。如果你的URL 模式叫做comment,而另外一个应用中也有一个同样的名称,当你在模板中使用这个名称的时候不能保证将插入哪个URL。在URL 名称中加上一个前缀,比如应用的名称,将减少冲突的可能。我们建议使用myapp-comment 而不是comment。
名称空间
命名空间(英语:Namespace)是表示标识符的可见范围。一个标识符可在多个命名空间中定义,它在不同命名空间中的含义是互不相干的。这样,在一个新的命名空间中可定义任何标识符,它们不会与任何已有的标识符发生冲突,因为已有的定义都处于其它命名空间中。
urlpatterns = [ re_path(r'^', include(('rbac.urls', 'rbac'),namespace='rbac')), ]
rbac/urls.py
urlpatterns = [ path('permission/patch/', views.PermissionPatch.as_view(), name='permission_patch'), path('show_permission_menu', views.PermissionMenu.as_view(), name='show_permission_menu') ]
views.py
reverse('rbac:permission_patch')
permission_path.html
{% url 'rbac:permission_path' %}
浙公网安备 33010602011771号