django中URL的命名空间总结(include/namespace/app_name)
前言介绍
一般在Django中有以下两种场景:
- 项目工程只有一个应用,但是有个特殊场景,比如学生管理应用,需要给男生和女生配置不同的URL前缀
- 项目工程会有多个应用,每个应用中可能存在相同的URL别名,比如都会有
name=index
首页
场景二在Django中比较常见,在template模板是进行URL解析的时候,需要区分不同的应用的,所以需要定义不同的app_name
app_name
目的:区分不同应用的URL地址
案例,项目工程中存在两个应用 ,blog 和 todo ,项目结构
1 | # 创建工程 |
因为是作为演示,但是没有具体model模型,只需要定义view视图函数和对应的URL地址、模板文件(进行URL解析演示)
1 | # blog |
Todo 的结构和内容与Blog很相似,这里不做代码展示
配置入口URL和 启动服务
1 | # django_namespace_demo/urls.py |
1、访问blog首页,正常显示(这个时候是从入口URL正常进入,有path前缀 )
2、访问detail, 访问之后发现跳转错误到了 todo detail
而不是 blog detail
所以需要指定
应用空间
来说明具体跳转到那个应用的detail
3、修改URL代码
1 | # blog/urls.py |
4、修改template模板代码 (📢: detail前面都添加了 app_name)
1 | <!-- blog/templates/blog/index.html --> |
5、然后重新访问 blog首页(http://127.0.0.1:8007/blog/) 或者 todo 首页 (http://127.0.0.1:8007/todo/)之后点击页面的 Visit Detail
超链接,发现跳转正常。
blog的visit detail跳转到了 blog 的detail页面;
Todo的visit detail跳转到了 todo 的detail页面;
📢 这个时候是没有用到 namespace 配置项的哦~
namespace 项目级别的命令空间
目的: 区分同一个应用中的不同URL前缀
这里用学生管理应用作为案例介绍
1 | # 创建应用 |
视图函数
1 | # student/views.py |
Urls 配置
1 | # student/urls.py |
1、访问 http://127.0.0.1:8007/male/ 希望的结果是跳转之后应该是http://127.0.0.1:8007/male/login
但是从下图知道,跳转之后的路径有问题,不符合预期
2、修改urls
📢 因为是男女使用不同的前缀,那么我们知道
只配置
app_name 是没有作用的,因为app_name 对student应用而言只是一个值,而不是两个
修改项目入口的urls.py
1 | # django_namespace_demo/urls.py |
这个时候在后台其实报错了,错误如下
1 | django.core.exceptions.ImproperlyConfigured: Specifying a namespace in include() without providing an app_name is not supported. Set the app_name attribute in the included module, or pass a 2-tuple containing the list of patterns and app_name instead. |
提示需要在包含的模块中配置 app_name 属性,或者需要在传递一个二元组(包含patterns和app_name)才可以
第一种方式,在student的urls.py 配置 app_name
1 | # student/urls.py |
第二种方式,在项目入口的urls.py 中修改现有include配置
1 | # django_namespace_demo/urls.py |
同时也需要修改视图函数中 reverse的解析
1 | # student/views.py |
3、然后访问 http://127.0.0.1:8007/male/ 获取期望的结果
知识点
1、URL解析存在两个地方
一个是视图函数中,一般是 reverse
和redirect
结合使用; 用法为 return redirect(reverse("appname_or_namespace:url_aliasname"))
一个是template模板文件中,一般是{% url 'appname_or_namespace:url_aliasname'%}
2、应用视图中获取项目入口配置的namespace的方法
1 | current_namespace = request.resolver_match.namespace |
3、URL中include
的用法
1 | # 常规用法 |
4、如果视图中使用 render 利用 template解析页面的时候,需要在 INSTALLED_APPS
把应用添加上,不然提示找不到对应的 模板
当然这里有个前提是,我们使用的是TEMPALTES
中的 'APP_DIRS': True,
默认值
5、关于URL的解析reverse和 get_absolute_url 等知识点参考 django中URL反向解析总结(url/reverse/get_absolute_url)
Demo源码下载 https://gitee.com/colin5063/django-learnning-examples/tree/master/django_namespace_demo
如果觉得文章对你有用,请不吝点赞和关注公众号搜索 全栈运维
或者 DailyJobOps
个人博客 http://blog.colinspace.com/
知乎平台 https://www.zhihu.com/people/colin-31-49
django中URL的命名空间总结(include/namespace/app_name)
http://blog.colinspace.com/2022/10/19/django中URL的命名空间总结-namespace-app-name/