Django4.0 URL调度器-URL的反向解析
在 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 如何解决这一问题。