Django URL路由配置之反向解析

Django URL路由配置之反向解析

在Django项目实际开发中,经常需要获取某个具体对象的URL,为生成的内容配置URL链接。

例如下面这样一个很常见的场景,在页面中展示一个文章标题列表,且每个标题都被设计成一个超链接,单击该链接就进入对应文章的详细页面。通常情况下,我们首先会简单地将URLconf模块设计成类似【代码4-13】的形式。

【代码4-13】

复制代码
01  from django.urls import path
02  from . import views
03  
04  urlpatterns = [
05      path('article/<int:pk>/', views.article_pk),
06  ]

【代码分析】

在第05行代码中,通过path()函数包含了一个URL请求('article/<int:pk>/')对应的视图函数(views.article_pk)。

然后在前端HTML页面中,超链接<a>标签的href属性会被定义为类似"http://www.domain.com/ article/1/"的值。当然,其中的域名部分(www.domain.com)将会由Django框架负责处理,设计人员只需要关注路径(/article/1/)的部分。

上述这样的设计当然也能够行得通,但存在巨大隐患,即将来既难以维护,又难以修改。因为,当URLconf模块被修改后,设计人员势必将手动修改HTML页面中的每一个超链接<a>标签中硬编码的href属性值,其工作量是可想而知的。

于是,设计人员就需要一种既安全又可靠,还能具有自适应功能的机制。该机制能够实现当修改URLconf模块中的代码后,无须在项目源码中大范围手动修改全部失效的硬编码URL地址。

Django框架恰好提供了一种解决方案------在URL地址中提供一个name参数,并赋值一个自定义的、便于标记的字符串。通过这个name参数,可以反向解析URL链接、反向URL链接匹配或反向URL链接查询。

Django框架在需要解析URL链接地址的地方,对不同层级提供了不同的工具,用于URL链接反查,具体有以下3种方式:

  • 写前端HTML网页时,在模板语言中使用url模板标签。
  • 写视图函数时,使用Python语法的reverse()函数。
  • 写模型(model)实例时,使用get_absolute_url()方法。

上面的3种方式都依赖于首先在path()函数中为URL链接地址添加name属性。

下面,我们继续完善这个在页面中展示一个文章标题列表的实例。首先,需要重新定义URLconf模块,具体代码如下:

【代码4-14】

复制代码
01  from django.urls import path
02  
03  from . import views
04  
05  urlpatterns = [
06      #...
07      path('articles/<int:year>/', views.year_archive, name='article-year-archive'),
08      #...
09  ]

【代码分析】

在第07行代码中,在path()函数中新增了一个name参数(name='article-year-archive'),该参数主要在模板中使用。

然后,通过在模板(HTML页面)中引用上面的name参数,实现对文章标题列表的获取,具体代码如下:

【代码4-15】

【代码分析】

在第07~13行代码中,通过在HTML页面中使用for循环语句,实现了文章标题列表的显示。具体说明如下:

  • 在第09行代码中,在模板中通过引用上面定义的name参数(name='article-year-archive'),实现了文章标题链接的反向解析。

最后,在视图函数中编写实现URL链接地址反向解析的Python代码,具体如下:

【代码4-16】

复制代码
01  <a href="{% url 'article-year-archive' 2023 %}">
02      2023 Archive
03  </a>
04  
05  {# 或者使用for循环变量 #}
06  <ul>
07      {% for year in year_list %}
08          <li>
09              <a href="{% url 'article-year-archive' year %}">
10                  {{ year }} Archive
11              </a>
12          </li>
13      {% endfor %}
14  </ul>

【代码分析】

在第02行代码中,引入了反向解析模块reverse。

在第04~10行代码中,定义了反向解析视图函数redirect_to_year()。其中关键的是第09行代码,通过调用reverse()方法实现了name='article-year-archive'与URLconf模块中的该PATH路径的反向解析操作。

在URL链接地址中使用name参数时,可以包含任何自定义的字符串,但稍不注意可能就会出现重名冲突的问题。于是,为了解决这个问题,引出了"命名空间"的概念。

本文节选自《Django 5企业级Web应用开发实战(视频教学版)》,获出版社和作者授权发布。

相关推荐
子兮曰2 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰2 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
默_笙2 天前
🍙 给每个请求过安检:FastAPI 是怎么把校验写进类型注解的
python
爱勇宝2 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
qq_426003962 天前
启动playwright录制codegen生成自动化测试脚本
python·自动化
虎头金猫2 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
胡写代码2 天前
别再前后端各写一套表单校验了
java·后端
长沙三为智能科技2 天前
家政小程序开发从0到上线:五阶段交付流程与验收清单
python
伞伞悦读2 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
大勇前进2 天前
原生 PHP 还是 Laravel?小项目到底要不要上框架
后端