将Django应用添加到INSTALLED_APPS会发生什么?
情况是这样的。我有一个Django项目,里面安装了两个应用程序。这两个应用程序如果单独安装的话,运行得都很好。
但是当我把这两个应用程序都列在settings.INSTALLED_APPS里时,第一个应用程序的reverse()函数在处理网址时就出问题了。这让我觉得第二个应用程序里可能有个bug导致了这个问题。
如果我把app_2从settings.INSTALLED_APPS里去掉,app_1的url reverse()又能正常工作了。所以问题就变成了,当我把app_2加到settings.INSTALLED_APPS里时,发生了什么“魔法”?我应该在哪个地方找app_2的代码来解决这个问题呢?
更新:
我把问题缩小了一点,但情况变得更奇怪了。app_2里有一个admin.py文件,里面定义了一些自定义的管理视图。在这个文件里有一行代码调用了reverse:
reverse('init_script_view', args=['id_content'])
只要这行代码在admin.py文件里,所有对reverse()的调用都会失败,并抛出一个NoReverseMatch异常。如果我把这行代码去掉,其他的就都正常了。
2 个回答
没有看到代码,很难确定问题所在,但我猜app_1和app_2的urls.py
文件里可能有不同的链接用的是相同的名字,比如:
app_1/urls.py:
...
url(r'^app_1/foo/$', 'app_1.views.foo', name='foo')
...
app_2/urls.py:
...
url(r'^app_2/foo/$', 'app_2.views.foo', name='foo')
...
如果你把这些名字整理一下(我见过的最常用的命名方式是appname_viewname
),那么它应该就能正常工作了。
当你把一个应用添加到INSTALLED_APPS时,其实并不会发生什么特别的事情,但最重要的是,当你调用reverse()
时,它的视图会被检查。
reverse
的工作原理是导入项目中的所有视图,然后看看哪些视图的名字和你给的URL名字匹配。不过,这个过程有点脆弱,如果任何一个视图因为某种原因出错,或者无法被导入,reverse
就会失败。
你发现只有在包含app2后才出错,这说明app2中的某个视图有问题。你可以尝试在命令行中单独导入这些视图,看看会出现什么错误。
更新后编辑 感谢你提供的额外信息。我在自己的代码中也遇到过这种情况。这可能是因为在处理urlconf之前,管理员文件被导入了,所以这个reverse会出错。试着把admin.autodiscover()
这一行移动到urls.py的最底部,让它成为这个文件中的最后一行。