django2.X 路由兼容 include模块书写规范(尴尬的namespace)
Posted jrri
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django2.X 路由兼容 include模块书写规范(尴尬的namespace)相关的知识,希望对你有一定的参考价值。
在使用以往框架的项目路由urls文件时
urlpatterns = [
url(r‘^user/‘,include(‘user.urls‘, namespace=‘user‘)),
url(r‘^‘,include(‘goods.urls‘,namespace=‘goods‘)),
]
错误信息:
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.
解决方法:
分别单独设置url路由文件路径, app_name应用名称 以及 namespace名称空间.
格式如下:
urlpatterns = [ url(r‘^user/‘,include((‘user.urls‘, ‘user‘), namespace=‘user‘)), url(r‘^‘,include((‘goods.urls‘, ‘goods‘), namespace=‘goods‘)), ]
或者
只设置应用url路由文件路径, namespace与url路径所在应用名同名.
格式如下:
urlpatterns = [ url(r‘^user/‘,include(‘user.urls‘)), url(r‘^‘,include(‘goods.urls‘)), ]
附:
如果是应用中的url路由文件使用include函数, 则可是在文件中添加变量 app_name=[‘应用名‘] 来解决问题.
----------------------------------------
原因分析
查看源代码
可得知:
django2.X中, 在include模块里, 对于app_name应用名称更新了的输入规范.
include要求的三个参数:
urlconf_module,url文件路径
app_name,包名
namespace,命名空间
三个属性中:
子url文件路径必须传入, 除此以外.
可以不传入app_name, 也可以不传入namespace, 甚至两个都不传入也都OK.
但是...
不可以只传入namespace!
不可以只传入namespace!
不可以只传入namespace!
只传入应用url路由文件路径的话, 小名默认与应用名相同.
如果需要单独设置与应用名有别的小名, 则必须传入应用名.
源码片段:
def include(arg, namespace=None, app_name=None): if app_name and not namespace: raise ValueError(‘Must specify a namespace if specifying app_name.‘) if isinstance(arg, tuple): # callable returning a namespace hint if namespace: raise ImproperlyConfigured(‘Cannot override the namespace for a dynamic module that provides a namespace‘) urlconf_module, app_name, namespace = arg else: # No namespace hint - use manually provided namespace urlconf_module = arg if isinstance(urlconf_module, six.string_types): urlconf_module = import_module(urlconf_module) patterns = getattr(urlconf_module, ‘urlpatterns‘, urlconf_module) # Make sure we can iterate through the patterns (without this, some # testcases will break). if isinstance(patterns, (list, tuple)): for url_pattern in patterns: # Test if the LocaleRegexURLResolver is used within the include; # this should throw an error since this is not allowed! if isinstance(url_pattern, LocaleRegexURLResolver): raise ImproperlyConfigured( ‘Using i18n_patterns in an included URLconf is not allowed.‘) return (urlconf_module, app_name, namespace)
def include(arg, namespace=None): app_name = None if isinstance(arg, tuple): # Callable returning a namespace hint. try: urlconf_module, app_name = arg except ValueError: if namespace: raise ImproperlyConfigured( ‘Cannot override the namespace for a dynamic module that ‘ ‘provides a namespace.‘ ) raise ImproperlyConfigured( ‘Passing a %d-tuple to include() is not supported. Pass a ‘ ‘2-tuple containing the list of patterns and app_name, and ‘ ‘provide the namespace argument to include() instead.‘ % len(arg) ) else: # No namespace hint - use manually provided namespace. urlconf_module = arg if isinstance(urlconf_module, str): urlconf_module = import_module(urlconf_module) patterns = getattr(urlconf_module, ‘urlpatterns‘, urlconf_module) app_name = getattr(urlconf_module, ‘app_name‘, app_name) if namespace and not app_name: raise 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.‘, ) namespace = namespace or app_name # Make sure the patterns can be iterated through (without this, some # testcases will break). if isinstance(patterns, (list, tuple)): for url_pattern in patterns: pattern = getattr(url_pattern, ‘pattern‘, None) if isinstance(pattern, LocalePrefixPattern): raise ImproperlyConfigured( ‘Using i18n_patterns in an included URLconf is not allowed.‘ ) return (urlconf_module, app_name, namespace)
以上是关于django2.X 路由兼容 include模块书写规范(尴尬的namespace)的主要内容,如果未能解决你的问题,请参考以下文章
Django2.x版本路由系统的正则写法以及视图函数的返回问题
python Django2.X,报错 ‘learning_logs ’is not a registered namespace,如何解决?