Django4.0 URL调度器-使用正则表达式
如果路径和转化器语法不能很好的定义你的 URL 模式,你可以可以使用正则表达式。如果要这样做,请使用 re_path()
而不是 path()
。
在 Python 正则表达式中,命名正则表达式组的语法是 (?P<name>pattern)
,其中 name
是组名,pattern
是要匹配的模式。
这里是先前 URLconf
的一些例子,现在用正则表达式重写一下:
from django.urls import path, re_path
from . import views
urlpatterns = [
path('articles/2003/', views.special_case_2003),
re_path(r'^articles/(?P<year>[0-9]{4})/, views.year_archive),
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/, views.month_archive),
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/, views.article_detail),
]
这实现了与前面示例大致相同的功能,除了:
- 将要匹配的 URLs 将稍受限制。比如,10000 年将不在匹配,因为 year 被限制长度为4。
- 无论正则表达式进行哪种匹配,每个捕获的参数都作为字符串发送到视图。
当从使用 path()
切换到 re_path()
(反之亦然),要特别注意,视图参数类型可能发生变化,你可能需要调整你的视图。
使用未命名的正则表达式组
还有命名组语法,例如 (?P<year>[0-9]{4})
,你也可以使用更短的未命名组,例如 ([0-9]{4})
。
不是特别推荐这个用法,因为它会更容易在匹配的预期含义和视图参数之间引发错误。
在任何情况下,推荐在给定的正则表达式里只使用一个样式。当混杂两种样式时,任何未命名的组都会被忽略,而且只有命名的组才会传递给视图函数。
嵌套参数
正则表达式允许嵌套参数,Django 将处理它们并传递给视图。当转换时,Django 将试着填充给所有外部捕捉参数,忽略任何嵌套捕捉参数。考虑下面可选的带有页面参数的 URL 模式:
from django.urls import re_path
urlpatterns = [
re_path(r'^blog/(page-(\d+)/)?, blog_articles), # bad
re_path(r'^comments/(?:page-(?P<page_number>\d+)/)?, comments), # good
]
两个模式使用嵌套参数,并处理:例如, blog/page-2/
将匹配给 blog_articles
并带有2个参数:page-2/
和 2
。第二个模式为 comments
匹配 comments/page-2/
并带有设置为2的关键参数 page_number
。这个案例里的外部参数是一个非捕捉参数 (?:...) 。
blog_articles
视图需要反转最外层捕捉的参数,page-2/
在这里不需要参数,而 comments
可以在没有参数或 page_number
值的情况下反转。
嵌套捕捉参数在视图参数和 URL 直接创建一个强耦合,如 blog_articles
所示:视图接收部分 URL (page-2/
) 而不只是视图要的值。当反转时这种耦合更明显,因为反转视图我们需要传递一段 URL 而不是 page number
。
根据经验,只有当正则表达式需要一个参数但视图忽略它时,才捕捉该视图需要的值并使用非捕捉参数。
更多建议: