Django4 中文入门教程 Django4.0 URL调度器-URL的反向解析

2024-02-25 开发教程 Django4 中文入门教程 匿名 5

在 Django 项目中,一个常见需求是获取最终形式的 URL,比如用于嵌入生成的内容中(视图和资源网址,给用户展示网址等)或用户服务器端的导航处理(重定向等)。

强烈建议不要硬编码 URL(这是一个费力、不能扩展、容易出错的主意)。同样危险的是设计临时机制来生成的 URL 与URLconf描述的设计的URL一样,这会导致 URL 随着时间的推移变得过时。

换句话说,需要的是 DRY 机制。除其他优势外,它还允许 URL 设计自动更新,而不必遍历所有项目代码来搜索和替换过时的 URL 。

我们用来获取 URL 的首要信息是负责处理它的视图的标识(例如名称)。必须参与查找正确网址的其他信息是视图参数的类型(位置、关键字)和值。

Django 提供了一个解决方案,使得 URL 映射是 URL 设计唯一的仓库。你使用 URLconf 来填充它,然后可以双向使用它:

  • 从用户/浏览器请求的 URL 开始,它调用正确的Django视图,并从 URL 中提取它的参数需要的值。
  • 从相应的 Django 视图标识以及要传递给它的参数来获取相关联的 URL 。

Django 提供执行反转 URL 的工具,这些工具与需要 URL 的不同层匹配:

  • 在模板里:使用 url 模板标签。
  • 在 Python 编码:使用 ​reverse()​ 函数。
  • 在与 Django 模型实例的 URL 处理相关的高级代码中: ​get_absolute_url()​ 方法。

例如:

from django.urls import path
from . import views
urlpatterns = [
#...
path('articles/<int:year>/', views.year_archive, name='news-year-archive'),
#...
]

根据这个设计,与 ​year nnnn​ 相对应的 URL 是 ​/articles/<nnnn>/​ 。

你可以使用以下方式在模板代码中来获取它们:

<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>
{# Or with the year in a template context variable: #}
<ul>
{% for yearvar in year_list %}
<li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>
{% endfor %}
</ul>

或在Python代码中:

from django.http import HttpResponseRedirect
from django.urls import reverse
def redirect_to_year(request):
# ...
year = 2006
# ...
return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))

因为某些原因,如果决定改变每年已发布的文章存档内容的 URL ,你只需要改变 URLconf 中的条目即可。

在一些视图具有一般性质的场景下,URLs 和视图存在多对一关系。对于这些情况,当反转 URLs 时,视图名并不是一个足够好的标识符。阅读下一节来了解 Django 如何解决这一问题。