【Django】URL 调度器

URL dispatcher

干净、优雅的 URL 方案是高质量 Web 应用程序中的一个重要细节。 Django 允许您随意设计 URL,没有框架限制。

请参阅万维网创建者蒂姆·伯纳斯·李 (Tim Berners-Lee) 撰写的 Cool URIs don’t change,以获取有关为什么 URL 应该干净且可用的出色论据

Overview

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

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

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

How Django processes a request

当用户从 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 将调用适当的错误处理视图。请参阅下面的错误处理

在这里插入图片描述
在这里插入图片描述

Example

Here’s a sample 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")

Path converters

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

  • str - 匹配任何非空字符串,不包括路径分隔符“/”。 如果表达式中不包含转换器,则这是默认设置。
  • int - 匹配零或任何正整数。 返回一个整数。
  • slug - 匹配由 ASCII 字母或数字以及连字符和下划线字符组成的任何 slug 字符串。 例如,building-your-1st-django-site
  • uuid - 匹配格式化的 UUID。 为防止多个 URL 映射到同一页面,必须包含破折号且字母必须为小写。 例如,075194d3-6885-417e-a8a8-6c931e272f00。 返回一个 UUID 实例。
  • path - 匹配任何非空字符串,包括路径分隔符“/”。 这允许您匹配完整的 URL 路径,而不是像 str 那样匹配 URL 路径的一段

Registering custom path converters

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

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

正则表达式类属性,作为字符串。

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

一个 to_url(self, value) 方法,它处理将 Python 类型转换为要在 URL 中使用的字符串。 如果它不能转换给定的值,它应该引发 ValueError。 ValueError 被解释为不匹配,因此 reverse() 将引发 NoReverseMatch 除非另一个 URL 模式匹配。

在 Django 3.1 中更改:
支持提高 ValueError 以指示未添加匹配项。

For example:

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),
    ...
]

Using regular expressions

如果路径和转换器语法不足以定义您的 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() 或反之亦然时,特别重要的是要注意视图参数的类型可能会改变,因此您可能需要调整视图

Using unnamed regular expression groups

使用未命名的正则表达式组
以及命名组语法,例如 (?P<year>[0-9]{4}),您也可以使用较短的未命名组,例如 ([0-9]{4})。

这种用法不是特别推荐,因为它更容易在匹配的预期含义和视图的参数之间意外引入错误

无论哪种情况,都建议在给定的正则表达式中仅使用一种样式。 当两种样式混合时,任何未命名的组都将被忽略,并且只有命名的组被传递给视图函数。

Nested arguments

嵌套参数
正则表达式允许嵌套参数,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 匹配:page-2/2。评论的第二个模式将匹配 comments/page-2/关键字参数 page_number 设置为 2。在这种情况下,外部参数是非捕获参数 (?:...)。

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

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

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

What the URLconf searches against

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

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

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

URLconf 不查看请求方法。 换句话说,所有请求方法——POST、GET、HEAD 等——将被路由到相同 URL 的相同函数。

Specifying defaults for view arguments

指定视图参数的默认值
一个方便的技巧是为视图的参数指定默认参数。 这是一个示例 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 值。

Performance

urlpatterns 中的每个正则表达式在第一次访问时都会被编译。这使得系统速度极快。

Syntax of the urlpatterns variable

urlpatterns 应该是一系列 path() 和/或 re_path() 实例。

Error handling

当 Django 找不到所请求 URL 的匹配项时,或者当引发异常时,Django 会调用错误处理视图。 用于这些情况的视图由四个变量指定。 它们的默认值对于大多数项目应该足够了,但是通过覆盖它们的默认值可以进一步自定义。 有关完整详细信息,请参阅有关自定义错误视图的文档。 这些值可以在您的根 URLconf 中设置。 在任何其他 URLconf 中设置这些变量将不起作用。 值必须是可调用的,或者表示视图的完整 Python 导入路径的字符串,应该调用该路径来处理手头的错误情况。 变量是:

Including other URLconfs

在任何时候,您的 urlpattern 都可以“包含”其他 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),
    ])),
]

Captured parameters

包含的 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

Passing extra options to view functions

URLconfs 有一个hook,可以让你将额外的参数作为 Python 字典传递给你的视图函数。
path() 函数可以采用可选的第三个参数,该参数应该是传递给视图函数的额外关键字参数的字典
For example:

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')。 这种技术在联合框架中用于将元数据和选项传递给视图

处理冲突 可以有一个 URL 模式,它捕获命名的关键字参数,并在其额外参数字典中传递具有相同名称的参数。 发生这种情况时,将使用字典中的参数而不是 URL 中捕获的参数。

Passing extra options to include()

同样,您可以将额外的选项传递给 include() 并且包含的​​ URLconf 中的每一行都将传递额外的选项。
例如,这两个 URLconf 集在功能上是相同的:
set one:

# 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),
]

Set two:

# 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}),
]

处理冲突 可以有一个 URL 模式,它捕获命名的关键字参数,并在其额外参数字典中传递具有相同名称的参数。 发生这种情况时,将使用字典中的参数而不是 URL 中捕获的参数

Reverse resolution of URLs

处理 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 的不同层:

  • templates中:使用 url 模板标签
  • 在 Python 代码中:使用 reverse() 函数。
  • 在与处理 Django 模型实例的 URL 相关的更高级别代码中:get_absolute_url() 方法。

examples

Consider again this URLconf entry:

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>

Or in Python code:

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 为此提供的解决方案。

Naming URL patterns

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

在命名 URL 模式时,选择不太可能与其他应用程序选择的名称冲突的名称。如果你调用你的 URL 模式注释并且另一个应用程序做同样的事情,reverse() 找到的 URL 取决于你项目的 urlpatterns 列表中最后一个模式。

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

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

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

URL namespaces

Introduction

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

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

URL 命名空间分为两部分,都是字符串:

  • 应用程序命名空间
    这描述了正在部署的应用程序的名称。单个应用程序的每个实例都将具有相同的应用程序命名空间。例如,Django 的 admin 应用程序具有某种可预测的应用程序命名空间“admin”。
  • 实例命名空间
    这标识了应用程序的特定实例。实例命名空间在整个项目中应该是唯一的。但是,实例命名空间可以与应用程序命名空间相同。这用于指定应用程序的默认实例。例如,默认的 Django 管理实例的实例命名空间为“admin”。

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

命名空间也可以嵌套。命名 URL ‘sports:polls:index’ 将在命名空间 ‘polls’ 中查找名为 ‘index’ 的模式,该命名空间本身在顶级命名空间 ‘sports’ 中定义。

Reversing namespaced URLs

当给定一个命名空间的 URL(例如“polls:index”)来解析时,Django 将完全限定的名称分成几部分,然后尝试以下查找:

首先,Django 查找匹配的应用程序命名空间(在本例中为“polls”)。这将产生该应用程序的实例列表

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

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

如果当前没有应用程序,Django 会寻找一个默认的应用程序实例。默认应用程序实例是具有与应用程序命名空间匹配的实例命名空间的实例(在此示例中,名为“polls”的轮询实例)。

如果没有默认的应用程序实例,Django 将选择最后部署的应用程序实例,不管它的实例名称是什么。

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

如果有嵌套的命名空间,则对命名空间的每个部分重复这些步骤,直到只有视图名称未解析。然后将视图名称解析为已找到的命名空间中的 URL
Example
为了展示此解决策略的实际效果,请考虑本教程中投票应用程序的两个实例的示例:一个称为“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 namespaces and included URLconfs

包含的 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>)

For example:

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() 的命名空间参数指定实例命名空间。 如果未指定实例命名空间,它将默认为包含的 URLconf 的应用程序命名空间。 这意味着它也将是该命名空间的默认实例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好,对于django-apscheduler,可以使用多个调度和作业存储。下面是一个示例: ```python # settings.py SCHEDULER_JOBSTORES = { 'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite') } SCHEDULER_EXECUTORS = { 'default': ThreadPoolExecutor(20), 'processpool': ProcessPoolExecutor(5) } SCHEDULER_JOB_DEFAULTS = { 'coalesce': False, 'max_instances': 3 } SCHEDULER_API_ENABLED = True ``` 在这个例子中,我们定义了一个默认的作业存储,并使用了 SQLAlchemyJobStore。我们还定义了两个执行:一个默认的线程池执行,和一个进程池执行。最后,我们还启用了调度的 API。 在您的应用程序中,您可以创建多个调度并指定它们的作业存储和执行。例如: ```python # views.py from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.schedulers.blocking import BlockingScheduler scheduler1 = BackgroundScheduler(jobstores={'default': SQLAlchemyJobStore(url='sqlite:///scheduler1_jobs.sqlite')}, executors={'default': ThreadPoolExecutor(10)}, job_defaults={'coalesce': False, 'max_instances': 3}) scheduler2 = BlockingScheduler(jobstores={'default': SQLAlchemyJobStore(url='sqlite:///scheduler2_jobs.sqlite')}, executors={'default': ProcessPoolExecutor(5)}, job_defaults={'coalesce': False, 'max_instances': 1}) ``` 在这个例子中,我们创建了两个调度:scheduler1 和 scheduler2。它们分别使用不同的作业存储和执行,并提供了不同的作业默认值。 希望这个示例能帮助您理解如何在django-apscheduler中使用多个调度和作业存储。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值