django 2.0 中URL的include方法使用分析
一、问题出现:
在使用Django2.0,配置全局URL时,希望指向某个APP的URL,配置如下:
from django.contrib import admin
from django.conf.urls import url,include
urlpatterns = [
url(r'^admin/', admin.site.urls),
# 配置users应用的URL
url(r'^users/', include('users.urls', namespace='users')),
]
运行该项目,会出现报错:
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.
而使用Django1.0,则会可以正常运行。
二、原因分析:
在Django1.0中include的源码是:
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 app_name:
warnings.warn(
'The app_name argument to django.conf.urls.include() is deprecated. '
'Set the app_name in the included URLconf instead.',
RemovedInDjango20Warning, stacklevel=2
)
是可以接收app_name参数的,而在Django2.0中:
def include(arg, namespace=None):
app_name = None
if isinstance(arg, tuple):
# Callable returning a namespace hint.
try:
urlconf_module, app_name = arg
是不能接收app_name参数的,那么如何将参数传给app_name呢;
既然2.0是1.0的升级版,肯定有方法解决这个问题,查看官方文档中对include的介绍:
-
..........
include()
also accepts as an argument either an iterable that returns URL patterns or a 2-tuple containing such iterable plus the names of the application namespaces.Parameters:
文档中指明是可以传入module的,传给变量arg的,没有传给app_name,文中提示可以传入2个参数的元组给arg,源码中有:
if isinstance(arg, tuple):
# Callable returning a namespace hint.
try:
urlconf_module, app_name = arg
说明第二个元组的参数会传给app_name,找到问题解决的方法。
三、解决方案
解决问题将URL配置换成:
url(r'^users/', include(('users.urls', 'users'), namespace='users')),
可正常启动。
四、补充
在官方文档中提示:
Changed in Django 2.0:
In older versions, this function is located in django.conf.urls
. The old location still works for backwards compatibility.
URL中的include方法之前1.0在 django.conf.urls 下,而2.0在 django.urls 下,但是之前位置还可以引用,说明在2.0中以下两种方式引用都是可以的:
from django.urls import include
from django.conf.urls import include