Django 2.0中使用include指定namespace报错的技术问询
解决Django 2.0+ include namespace报错的两种优雅方案
这个问题我之前帮朋友排查过,Django 2.0对URL命名空间的规则做了严格调整,你遇到的报错是典型的新旧版本规则不兼容问题。下面给你两种更优雅的解决方法,比直接在根urls里写name要规范得多:
方法一:在被包含的API URL模块中声明app_name
这是Django官方推荐的做法,把命名空间和对应的URL模块绑定在一起:
- 打开
compositions/api/urls.py,在文件顶部添加一行代码声明app_name:
app_name = "compositions-api"
- 根目录下的urls.py保持你原来的写法即可:
url(r'^api/compositions/', include("compositions.api.urls", namespace="compositions-api"))
这样修改后,你依然可以用reverse('compositions-api:your-url-name')来反向解析视图,完全符合模块化设计的要求。
方法二:在include时直接传入包含app_name的元组
如果不想修改子模块的urls.py,可以直接在根urls里通过元组的方式传递app_name:
把原来的include代码改成下面这样:
url(r'^api/compositions/', include(("compositions.api.urls", "compositions-api"), namespace="compositions-api"))
这里的元组第一个元素是子模块的URL路径,第二个就是对应的app_name,Django会直接识别这个元组来匹配命名空间。
为什么你之前的尝试没生效?
你说已经在urls.py里定义了app_name但没解决问题,大概率是把这个变量写在了根目录的urls.py里,而不是compositions/api/urls.py中。Django要求app_name必须属于被包含的那个URL模块,根urls里的app_name不会被关联到子模块的命名空间上,所以才会报错。
这两种方法都能保留URL模块化的优势,后续维护和扩展API路由时会更方便,比直接在根urls里硬编码name要更符合Django的最佳实践。
内容的提问来源于stack exchange,提问作者Ernst Plesiutschnig
相关产品推荐
相关产品推荐

