# Django 3.2.11.dev 文档

# `django.urls` 实用函数

## reverse()

如果你需要在你的代码中使用类似于 `url` 模板标签的东西，Django 提供了以下函数：

`reverse`(viewname, urlconf=None, args=None, kwargs=None, current_app=None)

`viewname` 可以是一个 URL 模式名称 或者是可调用的视图对象。例如，给定以下 `url`：

    from news import views

    path('archive/', views.archive, name='news-archive')

你可以使用以下任何一种方式来反查 URL：

    # using the named URL
    reverse('news-archive')

    # passing a callable object
    # (This is discouraged because you can't reverse namespaced views this way.)
    from news import views
    reverse(views.archive)

如果 URL 接受参数，你可以在 `args` 中传递参数。例如：

    from django.urls import reverse

    def myview(request):
        return HttpResponseRedirect(reverse('arch-summary', args=[1945]))

你也可以通过 `kwargs` 代替 `args`。例如：

    >>> reverse('admin:app_list', kwargs={'app_label': 'auth'})
    '/admin/auth/'

`args` 和 `kwargs` 不能同时传递给 `reverse()`。

如果不能匹配，`reverse()` 会引发一个 `NoReverseMatch` 异常。

`reverse()` 函数可以反查 URL 的多种正则表达式模式，但不是每一种可能的模式。目前主要的限制是，模式不能包含使用竖条（`"|"`）字符的替代选择。你可以很高兴地使用这样的模式与传入的 URL 进行匹配，并将它们发送给视图，但你不能反查这样的模式。

`current_app` 参数允许你向解析器提供一个提示，说明当前执行的视图属于哪个应用程序。这个 `current_app` 参数被用作提示，以便根据 命名空间的 URL 解析策略，将应用程序名称空间解析为特定应用程序实例上的 URL。

`urlconf` 参数是 URLconf 模块，其中包含用于反查的 URL 模式。默认情况下，使用的是当前线程的根 URLconf。

注解

`reverse()` 返回的字符串已经是 url 转义的。例如：

    >>> reverse('cities', args=['Orléans'])
    '.../Orl%C3%A9ans/'

对 `reverse()` 的输出应用进一步的编码（如 `urllib.parse.quote()`）可能会产生不理想的结果。

## `reverse_lazy()`

reverse() 的惰性执行版本。

`reverse_lazy`(viewname, urlconf=None, args=None, kwargs=None, current_app=None)

当你需要在你的项目的 URLConf 被加载之前使用 URL 反查时，这个功能很有用。一些常见的需要使用该功能的情况是：

- 提供一个反查的 URL 作为基于类的通用视图的 `url` 属性。
- 为装饰器提供一个反查的 URL（例如 `django.contrib.auth.decorators.permission_required()` 装饰器的 `login_url` 参数）。
- 提供一个反查的 URL 作为函数签名中参数的默认值。

## `resolve()`

`resolve()` 函数可用于解析到相应视图函数的 URL 路径。该函数的签名如下：

`resolve`(path, urlconf=None)

`path` 是你要解析的 URL 路径。与 `reverse()` 一样，你不需要担心 `urlconf` 参数。该函数返回一个 `ResolverMatch` 对象，允许你访问关于解析 URL 的各种元数据。

如果 URL 没有解析，函数会引发一个 `Resolver404` 异常（`Http404` 的一个子类）。

class `ResolverMatch`
  `func`

    用于服务 URL 的视图函数。

  `args`

    从 URL 中解析出的传递给视图函数的参数。

  `kwargs`

    从 URL 中解析出的可能传递给视图函数的关键字参数。

  `url_name`

    与 URL 匹配的 URL 模式的名称。

  `route`

    匹配 URL 模式的路径。

    例如，如果 `path('users/<id>/', ...)``是匹配的模式，``route` 将包含 `'users/<id>/'`。

  `tried`
    New in Django 3.2.

    The list of URL patterns tried before the URL either matched one or exhausted available patterns.

  `app_name`

    匹配 URL 模式的应用程序命名空间。

  `app_names`

    匹配 URL 模式的完整应用程序命名空间中的单个命名空间组件列表。例如，如果 `app_name` 是 `'foo:bar'`，那么 `app_names` 将是 `['foo', 'bar']`。

  `namespace`

    匹配 URL 模式的实例命名空间。

  `namespaces`

    匹配 URL 模式的完整实例命名空间中的单个命名空间组件列表，即，如果命名空间是 `foo:bar`，那么命名空间将是 `['foo'，'bar']`。

  `view_name`

    匹配 URL 的视图名称，包括命名空间（如果有的话）。

然后可以查询一个 `ResolverMatch` 对象，以提供与 URL 相匹配的 URL 模式的信息：

    # Resolve a URL
    match = resolve('/some/path/')
    # Print the URL pattern that matches the URL
    print(match.url_name)

一个 `ResolverMatch` 对象也可以解包为以下三个：

    func, args, kwargs = resolve('/some/path/')

`resolve()` 的一个可能的用法是测试一个视图在重定向到它之前是否会引发 `Http404` 错误：

    from urllib.parse import urlparse
    from django.urls import resolve
    from django.http import Http404, HttpResponseRedirect

    def myview(request):
        next = request.META.get('HTTP_REFERER', None) or '/'
        response = HttpResponseRedirect(next)

        # modify the request and response as required, e.g. change locale
        # and set corresponding locale cookie

        view, args, kwargs = resolve(urlparse(next)[2])
        kwargs['request'] = request
        try:
            view(*args, **kwargs)
        except Http404:
            return HttpResponseRedirect('/')
        return response

## `get_script_prefix()`

`get_script_prefix`()

通常情况下，你应该总是使用 `reverse()` 来定义应用程序中的 URL。然而，如果你的应用程序自己构造了部分 URL 层次结构，你可能偶尔需要生成 URL。在这种情况下，你需要能够在 Web 服务器中找到 Django 项目的基本 URL（通常，`reverse()` 会帮你处理这个问题）。在这种情况下，你可以调用 `get_script_prefix()`，它将返回 Django 项目的 URL 的脚本前缀部分。如果你的 Django 项目是在 web 服务器的根目录下，那么它总是 `"/"`。