我正在尝试将相当大的Django项目升级到新发布的Django 1.4,并且在运行python manage.py test
时遇到了一些问题。
许多在Django 1.3中传递的内部测试现在都失败了,我似乎无法修复奇怪的消息。看起来最多的是:
NoReverseMatch: u'admin' is not a registered namespace
这是针对密码更改的django.contrib.auth
测试引发的(其中一个是test_password_change_fails_with_mismatched_passwords (django.contrib.auth.tests.views.ChangePasswordTest)
。奇怪的是,命名空间已正确注册,应用程序运行正常。我正在导入管理员以“新”的方式:
url(r'^admin/', include(admin.site.urls)),
特别是当我谷歌这个错误时,我所能找到的只是使用旧方案导入管理URL的人,而且根本不涉及这个问题。
我尝试逐个从INSTALLED_APPS
删除应用,但验证测试根本无法通过。此外,当我从python manage.py shell
加载Python解释器并执行reverse('admin:index')
时,URL会解析为/admin/
且没有错误。我已经仔细阅读了这段代码,但却看不出它会落在哪里。
正如我前面提到的,这不是唯一发生的错误。即使在我的AttributeError: AUTH_PROFILE_MODULE
文件中定义了test_site_profile_not_available (django.contrib.auth.tests.models.ProfileTestCase)
,我也会从AUTH_PROFILE_MODULE
测试中获得settings.py
。 Django自己的测试怎么会像这样失败?
答案 0 :(得分:14)
简答:你有一个Django管理模板文件的副本从早期版本的Django复制到你的应用程序的模板目录中,然后你升级了Django但没有更新(重新复制) )那些本地模板。
长答案:此问题的主要原因是使用较旧版本的Django管理模板文件(安装在django本身的地方,通常是python的site-packages
或{{1 }} 目录)。 Django 1.5中有关于url模板标记的向后不兼容的更改,其中第一个参数必须是来自Django 1.5 release notes的字符串:
一个值得注意的弃用功能是转向“新式”网址 标签。在Django 1.3之前,解释了{%url myview%}之类的语法 不正确(Django认为“myview”是一个文字名称 视图,而不是名为myview的模板变量。 Django 1.3及以上版本 引入了{%load url from future%}语法来引入 纠正了将myview视为变量的行为。
所以,问题是你在app的模板文件夹中有一份admin的模板文件,这是从早期版本的Django中获得的。这通常用于覆盖默认管理模板。由于注意到向后不兼容的更改,这些过时的模板文件无法在较新的Django环境中加载,并导致奇怪的错误:dist-packages
。
更改NoReverseMatch: u'admin' is not a registered namespace
条目的顺序将忽略本地管理模板修改,而忽略默认模板文件(因为默认Django模板是通过TEMPLATE_LOADERS
的完整路径加载的)。如果需要进行修改(通常是这种情况),则必须从新的Django安装模板更新本地管理模板文件,然后在其上重新应用修改。
注1:类似的情况是本地管理模板比Django安装的默认值更新,这似乎是你的情况。同样,更好的解决方法是更新管理模板的所有副本。
注2:获得此类错误的另一种可能性是使用virtualenv时。例如,如果您使用virtualenv运行项目,但Django管理模板的filesystem.Loader
条目是您的全局python安装,则可能会出现此错误。
答案 1 :(得分:9)
事实证明,这是由于我的设置文件中TEMPLATE_LOADERS
键的顺序。
我有以下内容:
TEMPLATE_LOADERS = (
'django.template.loaders.app_directories.Loader',
'django.template.loaders.filesystem.Loader',
)
在某种程度上,在撤消管理URL时导致错误。切换两轮解决了这个问题。我很想知道这是怎么发生的,因为它在一个空白的Django 1.4项目中是不可重现的。
的重现性是AttributeError
的{{1}}。事实证明这是Django 1.4中的一个错误,它是在发布日here提交的。
答案 2 :(得分:5)
尝试添加命名空间=" admin"在urls.py文件中的include方法中。
ex:url(r' ^ admin /',include(" someUrlpattern",namespace =" admin"))
答案 3 :(得分:2)
app_directories模板加载器从INSTALLED_APPS模板目录加载模板,而文件系统加载器从TEMPLATE_DIRS设置中配置的模板目录加载它们。
切换其中两个会产生很大的不同,因为如果您的应用中有自定义模板,则app_directories位于顶部时将无法加载。如果文件系统加载器位于顶部,则django将首先在模板目录中查找模板,然后从installed_apps加载默认模板。
这就是为什么它在一个空白的Django项目中不可重现的原因。它会在适当的位置寻找模板。
答案 4 :(得分:0)
我的解决方案是将django升级到最新的版本: pip install --upgrade django == 1.6.1 在此之前,检查您安装的版本: pip冻结| grep Django - 我发现在发布服务器上有一个旧版本,升级解决了这个问题!
答案 5 :(得分:0)
我发生了类似的错误消息,因为我的网址配置了2个logout
网址。
urlpatterns = [
url(r'^$', TemplateView.as_view(template_name='home.html'), name='home'),
url(r'^api/v1/', include(router.urls)),
url(r'^logout/$', auth_views.logout, name='logout'),
url(r'^login/$', auth_views.login, {'template_name': 'login.html'}, name='login'),
url(r'^logout/$', auth_views.logout, {'template_name': 'logged_out.html'}, name='logout'),
]