URL 分发器

简洁优雅的 URL 方案是高质量 Web 应用程序的重要细节。Django 允许您根据需要设计 URL,没有任何框架限制。

参见 Cool URIs don’t change,由万维网创建者 Tim Berners-Lee 撰写,其中对为什么 URL 应该简洁易用给出了很好的论据。

概述

要为应用程序设计 URL,您需要创建一个非正式称为 **URLconf**(URL 配置)的 Python 模块。此模块是纯 Python 代码,是 URL 路径表达式与 Python 函数(您的视图)之间的映射。

此映射可以根据需要任意长短。它可以引用其他映射。而且,因为它只是纯 Python 代码,所以可以动态构建。

Django 还提供了一种根据活动语言翻译 URL 的方法。有关更多信息,请参见 国际化文档

Django 如何处理请求

当用户请求您由 Django 提供支持的网站上的页面时,系统将遵循以下算法来确定要执行哪个 Python 代码。

  1. Django 确定要使用的根 URLconf 模块。通常,这是 ROOT_URLCONF 设置的值,但是如果传入的 HttpRequest 对象具有 urlconf 属性(由中间件设置),则其值将用于代替 ROOT_URLCONF 设置。

  2. Django 加载该 Python 模块并查找变量 urlpatterns。这应该是一个 序列,包含 django.urls.path() 和/或 django.urls.re_path() 实例。

  3. Django 按顺序遍历每个 URL 模式,并在找到第一个与请求的 URL 匹配的模式时停止,匹配的是 path_info

  4. 一旦某个 URL 模式匹配,Django 就会导入并调用给定的视图,这是一个 Python 函数(或一个 基于类的视图)。视图将传递以下参数:

    • 一个 HttpRequest 实例。

    • 如果匹配的 URL 模式不包含命名组,则正则表达式中的匹配项将作为位置参数提供。

    • 关键字参数由路径表达式匹配的任何命名部分组成,并被 django.urls.path()django.urls.re_path() 的可选 kwargs 参数中指定的任何参数覆盖。

  5. 如果没有 URL 模式匹配,或者在此过程中的任何点引发异常,Django 将调用适当的错误处理视图。请参见下面的 错误处理

示例

这是一个 URLconf 示例:

from django.urls import path

from . import views

urlpatterns = [
    path("articles/2003/", views.special_case_2003),
    path("articles/<int:year>/", views.year_archive),
    path("articles/<int:year>/<int:month>/", views.month_archive),
    path("articles/<int:year>/<int:month>/<slug:slug>/", views.article_detail),
]

备注

  • 要从 URL 中捕获值,请使用尖括号。

  • 捕获的值可以选择包含转换器类型。例如,使用 <int:name> 来捕获整数参数。如果不包含转换器,则匹配任何字符串(不包括 / 字符)。

  • 无需添加前导斜杠,因为每个 URL 都有前导斜杠。例如,它是 articles,而不是 /articles

示例请求

  • /articles/2005/03/ 的请求将与列表中的第三个条目匹配。Django 将调用函数 views.month_archive(request, year=2005, month=3)

  • /articles/2003/ 将与列表中的第一个模式匹配,而不是第二个模式,因为模式是按顺序测试的,第一个模式是第一个通过测试的模式。您可以随意利用此顺序来插入这样的特殊情况。在这里,Django 将调用函数 views.special_case_2003(request)

  • /articles/2003 将不与这些模式中的任何一个匹配,因为每个模式都要求 URL 以斜杠结尾。

  • /articles/2003/03/building-a-django-site/ 将与最后一个模式匹配。Django 将调用函数 views.article_detail(request, year=2003, month=3, slug="building-a-django-site")

路径转换器

默认情况下,可以使用以下路径转换器:

  • str - 匹配任何非空字符串,不包括路径分隔符 '/'。如果不包含转换器,则为默认值。

  • int - 匹配零或任何正整数。返回一个 int

  • slug - 匹配任何由 ASCII 字母或数字以及连字符和下划线字符组成的 slug 字符串。例如,building-your-1st-django-site

  • uuid - 匹配格式化的 UUID。为防止多个 URL 映射到同一页面,必须包含连字符,字母必须为小写。例如,075194d3-6885-417e-a8a8-6c931e272f00。返回一个 UUID 实例。

  • path - 匹配任何非空字符串,包括路径分隔符 '/'。这允许您根据完整的 URL 路径而不是像 str 那样根据 URL 路径的段进行匹配。

注册自定义路径转换器

对于更复杂的匹配要求,您可以定义自己的路径转换器。

转换器是一个包含以下内容的类:

  • 一个 regex 类属性,作为字符串。

  • 一个 to_python(self, value) 方法,用于将匹配的字符串转换为应传递给视图函数的类型。如果无法转换给定值,则应引发 ValueError。除非其他 URL 模式匹配,否则 ValueError 将被解释为不匹配,并因此向用户发送 404 响应。

  • 一个 to_url(self, value) 方法,用于将 Python 类型转换为要在 URL 中使用的字符串。如果无法转换给定值,则应引发 ValueError。除非其他 URL 模式匹配,否则 ValueError 将被解释为不匹配,并因此 reverse() 将引发 NoReverseMatch

例如:

class FourDigitYearConverter:
    regex = "[0-9]{4}"

    def to_python(self, value):
        return int(value)

    def to_url(self, value):
        return "%04d" % value

使用 register_converter() 在您的 URLconf 中注册自定义转换器类。

from django.urls import path, register_converter

from . import converters, views

register_converter(converters.FourDigitYearConverter, "yyyy")

urlpatterns = [
    path("articles/2003/", views.special_case_2003),
    path("articles/<yyyy:year>/", views.year_archive),
    ...,
]

自版本 5.1 起已弃用: 使用 django.urls.register_converter() 覆盖现有转换器已被弃用。

使用正则表达式

如果路径和转换器语法不足以定义您的 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,
    ),
]

这与之前的示例大致相同,不同之处在于

  • 将匹配的确切 URL 受到更多限制。例如,年份 10000 将不再匹配,因为年份整数被限制为正好四位数字。

  • 每个捕获的参数都作为字符串发送到视图,无论正则表达式进行何种匹配。

从使用 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-([0-9]+)/)?$", blog_articles),  # bad
    re_path(r"^comments/(?:page-(?P<page_number>[0-9]+)/)?$", comments),  # good
]

这两种模式都使用嵌套参数,并将解析:例如,blog/page-2/ 将匹配 blog_articles,并带有两个位置参数:page-2/2comments 的第二种模式将匹配 comments/page-2/,其中关键字参数 page_number 设置为 2。在这种情况下,外部参数是非捕获参数 (?:...)

blog_articles 视图需要反转最外层捕获的参数 page-2/ 或在这种情况下不带任何参数,而 comments 可以不带任何参数或 page_number 的值进行反转。

嵌套捕获的参数会在视图参数和 URL 之间创建强耦合,如 blog_articles 所示:视图接收 URL 的一部分 (page-2/),而不是视图感兴趣的唯一值。反转时这种耦合更加明显,因为要反转视图,我们需要传递 URL 片段而不是页码。

根据经验,只捕获视图需要使用的值,并在正则表达式需要参数但视图忽略该参数时使用非捕获参数。

URLconf 搜索的目标

URLconf 搜索请求的 URL,作为一个普通的 Python 字符串。这并不包括 GET 或 POST 参数,也不包括域名。

例如,在对 https://www.example.com/myapp/ 的请求中,URLconf 将查找 myapp/

在对 https://www.example.com/myapp/?page=3 的请求中,URLconf 将查找 myapp/

URLconf 不查看请求方法。换句话说,所有请求方法 – POSTGETHEAD 等 – 将针对相同 URL 路由到相同的函数。

指定视图参数的默认值

一个方便的技巧是为视图的参数指定默认参数。这是一个 URLconf 和视图示例。

# URLconf
from django.urls import path

from . import views

urlpatterns = [
    path("blog/", views.page),
    path("blog/page<int:num>/", 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 值。

性能

Django 在第一次访问 urlpatterns 列表时处理其中的正则表达式。后续请求通过 URL 解析器使用缓存的配置。

urlpatterns 变量的语法

urlpatterns 应该是一个 sequence,包含 path() 和/或 re_path() 实例。

错误处理

当 Django 找不到请求 URL 的匹配项,或发生异常时,Django 将调用错误处理视图。

用于这些情况的视图由四个变量指定。它们默认值应该足以满足大多数项目的需求,但可以通过覆盖它们的默认值来进一步定制。

有关完整详细信息,请参阅关于 自定义错误视图 的文档。

这些值可以在您的根 URLconf 中设置。在任何其他 URLconf 中设置这些变量将不起作用。

值必须是可调用对象,或者表示应该调用的视图的完整 Python 导入路径,以处理手头的错误情况。

这些变量是

包含其他 URLconf

在任何时候,您的 urlpatterns 都可以“包含”其他 URLconf 模块。这实际上是在其他 URL 下“根植”一组 URL。

例如,这是 Django 网站 本身的 URLconf 的摘录。它包含许多其他 URLconf。

from django.urls import include, path

urlpatterns = [
    # ... snip ...
    path("community/", include("aggregator.urls")),
    path("contact/", include("contact.urls")),
    # ... snip ...
]

每当 Django 遇到 include() 时,它都会剪掉与该点匹配的 URL 的任何部分,并将剩余的字符串发送到包含的 URLconf 以进行进一步处理。

另一种可能性是通过使用 path() 实例列表来包含其他 URL 模式。例如,考虑这个 URLconf。

from django.urls import include, path

from apps.main import views as main_views
from credit import views as credit_views

extra_patterns = [
    path("reports/", credit_views.report),
    path("reports/<int:id>/", credit_views.report),
    path("charge/", credit_views.charge),
]

urlpatterns = [
    path("", main_views.homepage),
    path("help/", include("apps.help.urls")),
    path("credit/", include(extra_patterns)),
]

在此示例中,/credit/reports/ URL 将由 credit_views.report() Django 视图处理。

这可以用来消除 URLconf 中重复的冗余,其中重复使用单个模式前缀。例如,考虑这个 URLconf。

from django.urls import path
from . import views

urlpatterns = [
    path("<page_slug>-<page_id>/history/", views.history),
    path("<page_slug>-<page_id>/edit/", views.edit),
    path("<page_slug>-<page_id>/discuss/", views.discuss),
    path("<page_slug>-<page_id>/permissions/", views.permissions),
]

我们可以通过只声明一次公共路径前缀并对不同的后缀进行分组来改进这一点。

from django.urls import include, path
from . import views

urlpatterns = [
    path(
        "<page_slug>-<page_id>/",
        include(
            [
                path("history/", views.history),
                path("edit/", views.edit),
                path("discuss/", views.discuss),
                path("permissions/", views.permissions),
            ]
        ),
    ),
]

捕获的参数

包含的 URLconf 将接收来自父 URLconf 的任何捕获的参数,因此以下示例是有效的。

# In settings/urls/main.py
from django.urls import include, path

urlpatterns = [
    path("<username>/blog/", include("foo.urls.blog")),
]

# In foo/urls/blog.py
from django.urls import path
from . import views

urlpatterns = [
    path("", views.blog.index),
    path("archive/", views.blog.archive),
]

在上面的示例中,捕获的 "username" 变量按预期传递给包含的 URLconf。

将额外选项传递给视图函数

URLconf 有一个钩子,允许您将额外的参数作为 Python 字典传递给您的视图函数。

path() 函数可以采用可选的第三个参数,该参数应该是要传递给视图函数的额外关键字参数的字典。

例如:

from django.urls import path
from . import views

urlpatterns = [
    path("blog/<int:year>/", views.year_archive, {"foo": "bar"}),
]

在这个例子中,对于请求 /blog/2005/,Django 将调用 views.year_archive(request, year=2005, foo='bar')

这种技术用于 syndication 框架 中,用于向视图传递元数据和选项。

处理冲突

URL 模式可能同时捕获命名关键字参数,并在其额外参数字典中传递相同名称的参数。发生这种情况时,将使用字典中的参数,而不是 URL 中捕获的参数。

include() 传递额外选项

类似地,您可以向 include() 传递额外选项,并且包含的 URLconf 中的每一行都将传递这些额外选项。

例如,这两组 URLconf 在功能上是相同的

集合一

# main.py
from django.urls import include, path

urlpatterns = [
    path("blog/", include("inner"), {"blog_id": 3}),
]

# inner.py
from django.urls import path
from mysite import views

urlpatterns = [
    path("archive/", views.archive),
    path("about/", views.about),
]

集合二

# main.py
from django.urls import include, path
from mysite import views

urlpatterns = [
    path("blog/", include("inner")),
]

# inner.py
from django.urls import path

urlpatterns = [
    path("archive/", views.archive, {"blog_id": 3}),
    path("about/", views.about, {"blog_id": 3}),
]

请注意,额外选项将 *始终* 传递给包含的 URLconf 中的 *每一行*,无论该行的视图是否实际接受这些选项为有效选项。因此,只有在确定包含的 URLconf 中的每个视图都接受您正在传递的额外选项时,此技术才有用。

URL 的反向解析

在 Django 项目中工作时,一个常见的需求是能够以最终形式获取 URL,无论是用于嵌入生成的內容(视图和资源 URL、显示给用户的 URL 等),还是用于服务器端的导航流程处理(重定向等)。

强烈建议避免硬编码这些 URL(一种费力、不可扩展且容易出错的策略)。同样危险的是设计与 URLconf 描述的设计平行的临时机制来生成 URL,这可能导致生成随着时间推移而过时的 URL。

换句话说,需要的是 DRY 机制。除其他优点外,它允许 URL 设计的演变,而无需遍历所有项目源代码来搜索和替换过时的 URL。

我们可用来获取 URL 的主要信息是负责处理它的视图的标识(例如名称)。其他必须参与查找正确 URL 的信息包括视图参数的类型(位置、关键字)和值。

Django 提供了一种解决方案,使得 URL 映射器是 URL 设计的唯一存储库。您可以用您的 URLconf 来馈送它,然后它可以双向使用。

  • 从用户/浏览器请求的 URL 开始,它调用正确的 Django 视图,并提供它可能需要的任何参数及其从 URL 中提取的值。

  • 从相应的 Django 视图的标识以及将传递给它的参数的值开始,获取关联的 URL。

第一个是我们前面几节中讨论过的用法。第二个被称为 *URL 的反向解析*、*反向 URL 匹配*、*反向 URL 查找*,或者简称为 *URL 反转*。

Django 提供了执行 URL 反转的工具,这些工具与需要 URL 的不同层相匹配

  • 在模板中:使用 url 模板标签。

  • 在 Python 代码中:使用 reverse() 函数。

  • 在与处理 Django 模型实例的 URL 相关的更高级别的代码中:get_absolute_url() 方法。

示例

再次考虑这个 URLconf 条目

from django.urls import path

from . import views

urlpatterns = [
    # ...
    path("articles/<int:year>/", views.year_archive, name="news-year-archive"),
    # ...
]

根据此设计,对应于年份 *nnnn* 的归档的 URL 为 /articles/<nnnn>/

您可以通过使用以下方式在模板代码中获得这些内容

<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>
{# Or with the year in a template context variable: #}
<ul>
{% for yearvar in year_list %}
<li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>
{% endfor %}
</ul>

或在 Python 代码中

from django.http import HttpResponseRedirect
from django.urls import reverse


def redirect_to_year(request):
    # ...
    year = 2006
    # ...
    return HttpResponseRedirect(reverse("news-year-archive", args=(year,)))

如果由于某种原因,决定应该更改发布年度文章存档内容的 URL,那么您只需要更改 URLconf 中的条目。

在视图具有通用性质的某些场景中,URL 和视图之间可能存在多对一的关系。对于这些情况,在反转 URL 时,视图名称不足以对其进行标识。阅读下一节以了解 Django 为此提供的解决方案。

命名 URL 模式

为了执行 URL 反转,您需要使用如上例所示的 **命名 URL 模式**。用于 URL 名称的字符串可以包含任何您喜欢的字符。您不限于有效的 Python 名称。

命名 URL 模式时,选择不太可能与其他应用程序的名称选择冲突的名称。如果您将 URL 模式命名为 comment,而另一个应用程序也执行相同的操作,则 reverse() 找到的 URL 取决于项目 urlpatterns 列表中哪个模式最后。

在您的 URL 名称前加上前缀,可能源自应用程序名称(例如使用 myapp-comment 而不是 comment),可以减少冲突的可能性。

如果您想覆盖视图,您可以故意选择与另一个应用程序的 *相同 URL 名称*。例如,一个常见的用例是覆盖 LoginView。Django 的部分内容和大多数第三方应用程序都假定此视图具有名为 login 的 URL 模式。如果您有自定义登录视图并将其 URL 命名为 login,则 reverse() 将找到您的自定义视图,只要它在 urlpatterns 中位于 django.contrib.auth.urls 包含之后(如果它被包含)。

如果它们的參數不同,您也可以为多个 URL 模式使用相同的名称。除了 URL 名称之外,reverse() 还匹配参数的数量和关键字参数的名称。路径转换器也可以引发 ValueError 来指示没有匹配项,有关详细信息,请参阅 注册自定义路径转换器

URL 命名空间

介绍

URL 命名空间允许您唯一地反转 命名 URL 模式,即使不同的应用程序使用相同的 URL 名称。对于第三方应用程序来说,始终使用命名空间 URL 是一种好习惯(就像我们在教程中所做的那样)。类似地,如果您部署了应用程序的多个实例,它也允许您反转 URL。换句话说,由于单个应用程序的多个实例将共享命名的 URL,因此命名空间提供了一种区分这些命名 URL 的方法。

正确使用 URL 命名空间的 Django 应用程序可以为特定站点部署多次。例如,django.contrib.admin 有一个 AdminSite 类,它允许您 部署多个 admin 实例。在一个后面的例子中,我们将讨论从教程中在两个不同位置部署 polls 应用程序的想法,以便我们可以向两个不同的受众(作者和发布者)提供相同的功能。

URL 命名空间由两部分组成,这两部分都是字符串

应用程序命名空间

这描述了正在部署的应用程序的名称。单个应用程序的每个实例都将具有相同的应用程序命名空间。例如,Django 的 admin 应用程序具有可以预测的应用程序命名空间 'admin'

实例命名空间

这标识应用程序的特定实例。实例命名空间应在整个项目中唯一。但是,实例命名空间可以与应用程序命名空间相同。这用于指定应用程序的默认实例。例如,默认的 Django admin 实例的实例命名空间为 'admin'

命名空间 URL 使用 ':' 运算符指定。例如,admin 应用程序的主索引页面使用 'admin:index' 引用。这表示命名空间为 'admin',命名 URL 为 'index'

命名空间也可以嵌套。命名 URL 'sports:polls:index' 将在顶级命名空间 'sports' 内定义的命名空间 'polls' 中查找名为 'index' 的模式。

反转命名空间 URL

给定一个命名空间 URL(例如 'polls:index')进行解析时,Django 会将完全限定名拆分为多个部分,然后尝试以下查找

  1. 首先,Django 会查找匹配的应用程序命名空间(在此示例中为 'polls')。这将产生该应用程序实例的列表。

  2. 如果定义了当前应用程序,Django 会查找并返回该实例的 URL 解析器。可以使用 reverse() 函数的 current_app 参数指定当前应用程序。

    url 模板标签使用当前解析的视图的命名空间作为RequestContext中的当前应用程序。可以通过设置request.current_app 属性来覆盖此默认值。

  3. 如果没有当前应用程序,Django 将查找默认应用程序实例。默认应用程序实例是其实例命名空间应用程序命名空间匹配的实例(在此示例中,名为 'polls'polls 实例)。

  4. 如果没有默认应用程序实例,Django 将选择部署的最后一个应用程序实例,无论其实例名称是什么。

  5. 如果提供的命名空间在步骤 1 中与应用程序命名空间不匹配,Django 将尝试直接将命名空间查找为实例命名空间

如果存在嵌套命名空间,则对命名空间的每个部分重复这些步骤,直到只有视图名称未解析。然后,视图名称将在找到的命名空间中解析为 URL。

示例

为了展示这种解析策略的实际应用,考虑一下教程中polls应用程序的两个实例:一个名为'author-polls',另一个名为'publisher-polls'。假设我们已经增强了该应用程序,以便它在创建和显示投票时考虑实例命名空间。

urls.py
from django.urls import include, path

urlpatterns = [
    path("author-polls/", include("polls.urls", namespace="author-polls")),
    path("publisher-polls/", include("polls.urls", namespace="publisher-polls")),
]
polls/urls.py
from django.urls import path

from . import views

app_name = "polls"
urlpatterns = [
    path("", views.IndexView.as_view(), name="index"),
    path("<int:pk>/", views.DetailView.as_view(), name="detail"),
    ...,
]

使用此设置,可以进行以下查找

  • 如果其中一个实例是当前实例——例如,如果我们在实例'author-polls'中呈现详细信息页面——'polls:index'将解析为'author-polls'实例的索引页面;也就是说,以下两者都将导致"/author-polls/"

    在基于类的视图的方法中

    reverse("polls:index", current_app=self.request.resolver_match.namespace)
    

    以及在模板中

    {% url 'polls:index' %}
    
  • 如果没有当前实例——例如,如果我们在站点的其他地方呈现页面——'polls:index'将解析为polls的最后一个注册实例。由于没有默认实例('polls'的实例命名空间),将使用注册的polls的最后一个实例。这将是'publisher-polls',因为它在urlpatterns中最后声明。

  • 'author-polls:index'将始终解析为实例'author-polls'的索引页面('publisher-polls'也是如此)。

如果还有一个默认实例——即,一个名为'polls'的实例——则上述情况中唯一变化的是没有当前实例的情况(上列表中的第二项)。在这种情况下,'polls:index'将解析为默认实例的索引页面,而不是urlpatterns中最后声明的实例。

URL 命名空间和包含的 URLconf

包含的 URLconf 的应用程序命名空间可以通过两种方式指定。

首先,可以在包含的 URLconf 模块中设置app_name属性,该属性与urlpatterns属性位于同一级别。您必须将实际的模块或对模块的字符串引用传递给include(),而不是urlpatterns列表本身。

polls/urls.py
from django.urls import path

from . import views

app_name = "polls"
urlpatterns = [
    path("", views.IndexView.as_view(), name="index"),
    path("<int:pk>/", views.DetailView.as_view(), name="detail"),
    ...,
]
urls.py
from django.urls import include, path

urlpatterns = [
    path("polls/", include("polls.urls")),
]

polls.urls中定义的 URL 将具有应用程序命名空间polls

其次,您可以包含一个包含嵌入式命名空间数据的对象。如果您include()一个path()re_path()实例列表,则该对象中包含的 URL 将添加到全局命名空间。但是,您也可以include()一个包含以下内容的 2 元组:

(<list of path()/re_path() instances>, <application namespace>)

例如:

from django.urls import include, path

from . import views

polls_patterns = (
    [
        path("", views.IndexView.as_view(), name="index"),
        path("<int:pk>/", views.DetailView.as_view(), name="detail"),
    ],
    "polls",
)

urlpatterns = [
    path("polls/", include(polls_patterns)),
]

这会将指定的 URL 模式包含到给定的应用程序命名空间中。

可以使用include()namespace参数指定实例命名空间。如果没有指定实例命名空间,它将默认为包含的 URLconf 的应用程序命名空间。这意味着它也将是该命名空间的默认实例。

返回顶部