当我阅读Django代码时,有时会在一些模板中看到reverse()。我不太确定这是什么,但它与HttpResponseRedirect一起使用。如何以及何时应该使用这个reverse() ?
当前回答
reverse()用于坚持django的DRY原则,即如果你在未来改变url,那么你可以使用reverse(urlname)引用该url。
其他回答
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(不是/foo/)在一些其他的视图(不是some_view),你想重定向用户到/foo/(通常在成功提交表单的情况下)。
你可以这样做:
return HttpResponseRedirect('/foo/')
但是,如果将来想更改URL该怎么办呢?您必须更新urls.py以及代码中对它的所有引用。这违反了DRY(不要重复自己)原则和只在一个地方编辑的整个思想——这是需要努力的。
相反,你可以说:
from django.http import HttpResponseRedirect
from django.urls import reverse
return HttpResponseRedirect(reverse('url_name'))
这将查看项目中定义的所有URL,以查找名称为url_name的URL,并返回实际的URL /foo/。
这意味着你只能通过它的name属性来引用URL -如果你想改变URL本身或它引用的视图,你可以通过编辑一个地方来做到这一点- urls.py。
这是一个老问题,但这里有一些东西可能会帮助到一些人。
官方文件显示:
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,)))
有个医生可以解决这个问题
https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse-resolution-of-urls
它可以用来为给定的视图生成URL
主要的优点是您不必在代码中硬编码路由。
reverse()用于坚持django的DRY原则,即如果你在未来改变url,那么你可以使用reverse(urlname)引用该url。
现有的答案很好地解释了Django中的reverse()函数是什么。
然而,我希望我的回答能让你明白为什么:为什么在模板视图绑定中使用reverse()而不是其他更直接的,可以说是更python化的方法,以及在Django路由逻辑中“通过reverse()模式重定向”流行的一些合理原因。
一个关键的好处是反向构造url,正如其他人提到的那样。就像你如何使用{% url "profile"配置文件。Id %}从你的应用程序的url配置文件中生成url:id > /配置文件”视图。概要文件名称=“配置文件”)。
但是正如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块中的代码按照以下模式使用reverse和HttpResponseRedirect:
HttpResponseRedirect(reverse('polls:polls-results',
args=(question.id)
首先,这意味着我们不必硬编码URL(与DRY原则一致),但更重要的是,reverse()提供了一种优雅的方式,通过处理从参数解压缩的值来构造URL字符串(args=(question.id)由URLConfig处理)。假设问题有一个包含值5的属性id,那么从reverse()构造的URL将是:
'/polls/5/results/'
在普通的模板-视图绑定代码中,我们使用HttpResponse()或render(),因为它们通常涉及较少的抽象:一个视图函数返回一个模板:
def index(request):
return render(request, 'polls/index.html')
但是在许多重定向的合法情况下,我们通常关心从参数列表构造URL。这些情况包括:
通过POST请求提交HTML表单 验证后用户登录 通过JSON web令牌重置密码
其中大多数涉及某种形式的重定向和通过一组参数构造的URL。希望这能增加已经有用的答案!
推荐文章
- django MultiValueDictKeyError错误,我如何处理它
- 我如何在Django中创建一个鼻涕虫?
- 没有名为'django.core.urlresolvers'的模块
- Django - makemigrations -未检测到任何更改
- ">", "<", ">=" 和“< =”不工作”在Django过滤()”
- Django项目工作目录结构的最佳实践
- 如何在Django中表达一对多关系?
- 用Django创建电子邮件模板
- Django的嵌套元类是如何工作的?
- 用Django实现OpenID的最佳解决方案是什么?
- 在使用信号时,你不能在'原子'块的末尾执行查询,但只能在单元测试期间执行
- Django查询- id vs pk
- render(), render_to_response()和direct_to_template()之间有什么区别?
- 如何使用MySQLdb与Python和Django在OSX 10.6?
- 如何在Django中一次添加多个对象到ManyToMany关系?