首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么是reverse()?

什么是reverse()?
EN

Stack Overflow用户
提问于 2012-06-28 17:26:53
回答 7查看 163.6K关注 0票数 276

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

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2012-06-28 17:43:24

reverse() | Django documentation

让我们假设您在urls.py中定义了以下内容:

代码语言:javascript
复制
url(r'^foo$', some_view, name='url_name'),

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

代码语言:javascript
复制
<!-- 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>

这将呈现为:

代码语言:javascript
复制
<a href="/foo/">link which calls some_view</a>

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

你可以这样做:

代码语言:javascript
复制
return HttpResponseRedirect('/foo/')

但是,如果您想在将来更改URL呢?您必须更新您的urls.py以及代码中对它的所有引用。这违背了DRY (Don't Repeat Yourself)原则和只在一个地方编辑的整个想法--这是值得努力的东西。

相反,你可以说:

代码语言:javascript
复制
from django.urls import reverse
return HttpResponseRedirect(reverse('url_name'))

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

这意味着您只能通过它的name属性来引用URL -如果您想要更改URL本身或它所引用的视图,您可以通过编辑一个地方来实现这一点- urls.py

票数 423
EN

Stack Overflow用户

发布于 2019-04-06 17:48:23

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

然而,我希望我的回答能为为什么使用提供不同的答案:为什么在模板-视图绑定中使用reverse()而不是其他更直接、更有争议的方法,以及这种“通过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

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
HttpResponseRedirect(reverse('polls:polls-results',
                                        args=(question.id)

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

代码语言:javascript
复制
'/polls/5/results/'

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

代码语言:javascript
复制
def index(request):
    return render(request, 'polls/index.html') 

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

  • HTML表单通过POST请求提交
  • 用户登录post-validation
  • Reset密码通过JSON web令牌

其中大多数都涉及某种形式的重定向,以及通过一组参数构造的URL。希望这能为已经很有帮助的答案添加更多的线索!

票数 13
EN

Stack Overflow用户

发布于 2019-10-22 17:40:55

现有的答案是相当清楚的。以防您不知道它为什么被称为reverse:它接受url名称的输入,并给出实际的url,这与先有一个url,然后再给它一个名称是相反的。

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11241668

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档