在使用 Django 项目时, 一个常见的需求是获得 URL 的最终形式, 以用于嵌入到生成的内容中 (视图中和显示给用户的 URL 等) 或者用于处理服务器端的导航(重定向等).
人们强烈希望不要硬编码这些 URL(费力, 不可扩展且容易产生错误)或者设计一种与 URLconf 毫不相干的专门的 URL 生成机制, 因为这样容易导致一定程度上产生过期的 URL.
换句话讲, 需要的是一个 DRY 机制. 除了其它有点, 它还允许设计的 URL 可以自动更新而不用遍历项目的源代码来搜索并替换过期的 URL.
获取一个 URL 最开始想到的信息是处理它视图的标识, 查找正确的 URL 的其他必要的信息有视图参数的类型 (位置参数, 关键字参数) 和值.
Django 提供一个办法是让 URL 映射到 URL 设计唯一的地方.
你填充你的 URLconf, 然后可以双向使用它:
根据用户 / 浏览器发起的 URL 请求, 它调用正确的 Django 视图, 并从 URL 中提取它的参数需要的值.
根据 Django 视图的标识和将要传递给它的参数的值, 获取与之关联的 URL.
第二种方式叫做反向解析 URL, 反向 URL 匹配, 反向 URL 查询或简单的 URL 反查.
在需要 URL 的地方, 对于不同层级, Django 提供不同的工具用于 URL 反查
在模板中: 使用 url 模板标签
在 Python 代码中: 使用 django.core.urlesolvers.reverse()函数
在更高层的与处理 Django 模型实例相关的代码中: 使用 get_absolute_url()方法
简单来说, 就是可以给我们的 URL 匹配规则起个名字, 一个 URL 匹配模式起一个名字.
这样我们以后就不需要写死 URL 代码了, 只需要通过名字来调用当前的 URL.
比如:
- url(r"^home", views.home, name="home"), #给自己的 url 匹配模式起名为 home
- url(r"^index/(\d*)", views.index, name="index")# 给自己的 url 匹配模式起名为 index
这样, 在模板里面可以这样引用:
{% url "home" %}
在 views 函数中可以这样引用:
- from django.urls import reverse
- reverse("index", args=("2018", ))
示例, 看下面的 URLconf:
- from django.conf.urls import url
- from . import views
- urlpatterns = [
- url(r"^articles/([0-9]{4})/$", views.year_archive, name="new-year-archive")
- ]
根据上面代码的设计, 某一年 nnnn 对应的归档的 URL 是 / articles/nnnn
你可以在模板的代码中使用下面的方法获得它们:
- <a href="{% url" news-year-archive "2012 %}">
- 2012 Archive
- </a>
- <ul>
- {% for yearvar in year_list%}
- <li>
- <a href="{% ulr" news-year-archive "yearvar%}">
- {{ yearvar }} Archive
- </a>
- </li>
- {% endfor %}
- </ul>
在 Python 代码中, 这么使用:
- from django.urls import reverse
- from django.shortcuts import redirect
- def redirect_to_year(request):
- year = 2006
- return redirect(reverse("news-year-archive", args=(year, )))
如果出于某种原因决定按年归档文章的 URL 应该调整一下, 那么你将只需要修改 URLconf 中的内容.
在某些场景中, 一个视图是通用的, 所以在 URL 和视图之间存在多对一的关系.
对于这些情况, 当反查 URL 时, 只有视图的名字还不够.
注意:
为了完成上面例子中的 URL 反查, 你将需要使用命名的 URL 模式.
URL 名称使用的字符串可以包含任意字符, 不只限制在合法的 Python 名称.
当你命名你的 url 模式时, 请确保使用的名称不会与其它应用中名称冲突. 如果你的 URL 模式叫做[comment] , 而另外一个应用中也有一个同样的名称, 当你在模板中使用这个名称的时候不能保证将插入哪个 URL.
在 URL 名称中加上一个前缀, 比如应用的名称, 将减少冲突的可能. 例如采用[myapp-comment] , 而不是一个[comment] .
来源: http://www.bubuko.com/infodetail-2854699.html