286

当我有时阅读 Django 代码时,我会在一些模板中看到reverse()。我不太确定这是什么,但它与 HttpResponseRedirect 一起使用。reverse()这应该如何以及何时使用?

4

7 回答 7

434

reverse()| Django 文档


让我们假设在您urls.py的定义中:

url(r'^foo$', some_view, name='url_name'),

然后,您可以在模板中将此 url 引用为:

<!-- django <= 1.4 -->
<a href="{% url url_name %}">link which calls some_view</a>

<!-- django >= 1.5 or with {% load url from future %} in your template -->
<a href="{% url 'url_name' %}">link which calls some_view</a>

这将呈现为:

<a href="/foo/">link which calls some_view</a>

现在假设您想在您的中做类似的事情views.py- 例如,您正在处理其他一些 URL(not /foo/)在其他一些视图(not some_view)中,并且您希望将用户重定向到/foo/(通常是成功提交表单的情况)。

你可以这样做:

return HttpResponseRedirect('/foo/')

但是,如果您将来想更改 URL 怎么办?您必须在代码中更新您urls.py 所有对它的引用。这违反了DRY(不要重复自己)原则和仅在一个地方进行编辑的整个想法——这是值得努力的事情。

相反,你可以说:

from django.urls import reverse
return HttpResponseRedirect(reverse('url_name'))

这会在您的项目中定义的所有 URL 中查找使用名称定义的 URL,url_name并返回实际的 URL /foo/

这意味着您仅通过其name属性引用 URL - 如果您想更改 URL 本身或它所引用的视图,您可以通过仅编辑一个位置来执行此操作 - urls.py

于 2012-06-28T09:43:24.243 回答
14

现有的答案很清楚。以防万一您不知道为什么调用reverse它:它需要输入一个 url 名称并给出实际的 url,这与先有一个 url 然后给它一个名称相反。

于 2019-10-22T09:40:54.817 回答
13

现有的答案很好地解释了Django 中这个函数的含义。reverse()

但是,我希望我的回答能阐明为什么:为什么reverse()在模板视图绑定中使用代替其他更直接、可以说更pythonic的方法,以及这种“重定向通过 reverse()”流行的合理原因是什么?模式”在 Django 路由逻辑中。

正如其他人所提到的,一个关键的好处是 URL 的反向构造。就像您{% url "profile" profile.id %}从应用程序的 url 配置文件生成 url 一样:例如path('<int:profile.id>/profile', views.profile, name="profile").

但正如 OP 所指出的,使用reverse()也通常与使用 结合使用HttpResponseRedirect。但为什么?

我不太确定这是什么,但它与 HttpResponseRedirect 一起使用。这个 reverse() 应该如何以及何时使用?

考虑以下内容views.py

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

def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected = question.choice_set.get(pk=request.POST['choice'])
    except KeyError:
        # handle exception
        pass
    else:
        selected.votes += 1
        selected.save()
        return HttpResponseRedirect(reverse('polls:polls-results',
                                    args=(question.id)
        ))

而我们最小的urls.py

from django.urls import path
from . import views

app_name = 'polls'
urlpatterns = [
    path('<int:question_id>/results/', views.results, name='polls-results'),
    path('<int:question_id>/vote/', views.vote, name='polls-vote')
]

vote()函数中,我们else块中的代码使用reverseHttpResponseRedirect以下模式:

HttpResponseRedirect(reverse('polls:polls-results',
                                        args=(question.id)

这首先意味着我们不必对 URL 进行硬编码(符合 DRY 原则),但更重要的是,reverse()通过处理从参数中解包的值(args=(question.id)由 URLConfig 处理)提供了一种构造 URL 字符串的优雅方法。假设有一个包含 valuequestion的属性,则从 构造的 URL将是:id5reverse()

'/polls/5/results/'

在普通的模板视图绑定代码中,我们使用HttpResponse()orrender()因为它们通常涉及较少的抽象:一个视图函数返回一个模板:

def index(request):
    return render(request, 'polls/index.html') 

但在许多合法的重定向案例中,我们通常关心从参数列表构造 URL。这些包括以下情况:

  • POST通过请求提交 HTML 表单
  • 用户登录后验证
  • 通过 JSON Web 令牌重置密码

其中大多数涉及某种形式的重定向,以及通过一组参数构造的 URL。希望这增加了已经有帮助的答案线程!

于 2019-04-06T09:48:22.707 回答
11

这是一个老问题,但这里有一些可能对某人有帮助的东西。

来自官方文档:

Django 提供了用于执行 URL 反转的工具,这些工具与需要 URL 的不同层相匹配: 在模板中:使用 url 模板标签。在 Python 代码中:使用 reverse() 函数。在与处理 Django 模型实例的 URL 相关的更高级别代码中: get_absolute_url() 方法。

例如。在模板中(url 标签)

<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>

例如。在python代码中(使用reverse函数)

return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))
于 2017-06-02T03:58:28.433 回答
4

该函数支持干原则 - 确保您不会在整个应用程序中对 url 进行硬编码。一个 url 应该在一个地方定义,而且只有一个地方 - 你的 url conf。之后,您实际上只是在引用该信息。

用于reverse()为您提供页面的 url,给定视图的路径或 url conf 中的 page_name 参数。如果在模板中使用{% url 'my-page' %}.

您可以在很多地方使用此功能。我发现我使用它的一个地方是在视图中重定向用户时(通常在成功处理表单之后) -

return HttpResponseRedirect(reverse('thanks-we-got-your-form-page'))

您也可以在编写模板标签时使用它。

我使用的另一次reverse()是模型继承。我在父模型上有一个 ListView,但想从这些父对象中的任何一个获取它的关联子对象的 DetailView。我向父级附加了一个get__child_url()函数,该函数标识了一个子级的存在,并使用reverse().

于 2016-04-09T02:25:33.413 回答
3

有一个文档

https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse-resolution-of-urls

它可用于为给定视图生成 URL

主要优点是您不会在代码中对路由进行硬编码。

于 2012-06-28T09:35:00.940 回答
2

reverse()用于遵守 django DRY 原则,即如果您将来更改 url,那么您可以使用 reverse(urlname) 引用该 url 。

于 2014-12-02T17:53:09.217 回答