django.urls 实用函数

reverse()

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

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

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

  1. from news import views
  2. path('archive/', views.archive, name='news-archive')

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

  1. # using the named URL
  2. reverse('news-archive')
  3. # passing a callable object
  4. # (This is discouraged because you can't reverse namespaced views this way.)
  5. from news import views
  6. reverse(views.archive)

如果 URL 接受参数,你可以在 args 中传递参数。例如:

  1. from django.urls import reverse
  2. def myview(request):
  3. return HttpResponseRedirect(reverse('arch-summary', args=[1945]))

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

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

argskwargs 不能同时传递给 reverse()

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

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

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

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

注解

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

  1. >>> reverse('cities', args=['Orléans'])
  2. '.../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 Development version.

    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 模式的信息:

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

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

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

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

  1. from urllib.parse import urlparse
  2. from django.urls import resolve
  3. from django.http import Http404, HttpResponseRedirect
  4. def myview(request):
  5. next = request.META.get('HTTP_REFERER', None) or '/'
  6. response = HttpResponseRedirect(next)
  7. # modify the request and response as required, e.g. change locale
  8. # and set corresponding locale cookie
  9. view, args, kwargs = resolve(urlparse(next)[2])
  10. kwargs['request'] = request
  11. try:
  12. view(*args, **kwargs)
  13. except Http404:
  14. return HttpResponseRedirect('/')
  15. return response

get_script_prefix()

get_script_prefix()

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