Django4 中文入门教程 Django4.0 URL调度器-使用正则表达式

2024-02-25 开发教程 Django4 中文入门教程 匿名 2

如果路径和转化器语法不能很好的定义你的 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​。

根据经验,只有当正则表达式需要一个参数但视图忽略它时,才捕捉该视图需要的值并使用非捕捉参数。