我有一个Django项目。这个Django项目的一部分是一个报告模块,它在所有INSTALLED_APPS中搜索报告目录,非常类似于管理界面的自动发现机制。
这个模块有一个小的注册类,可以注册找到的类。以非常简单的方式看起来像这样:
def autodiscover():
"""
Searches for reports module in all INSTALLED_APPS
"""
global REPORTSLOADING
if REPORTSLOADING:
return
REPORTSLOADING = True
import imp
from django.conf import settings
for app in settings.INSTALLED_APPS:
try:
app_path = import_module(app).__path__
except AttributeError:
continue
try:
imp.find_module('reports', app_path)
except ImportError:
continue
import_module("%s.reports" % app)
REPORTSLOADING = False
class ReportsRegistery(object):
.....
registery = ReportsRegistery()
如果任何INSTALLED_APPS需要注册一个Report类,我们需要reports/__init__.py
内的一行:
import reports
reports.registery.register(SomeReportClass)
在主urls.py中,我会这样做:
import reports
reports.autodiscover()
urlpatterns = patterns('',
....
(r'', include(reports.registery.urls)),
)
现在我决定为它创建一个可插入的django应用程序,并将相同的代码放在包的__init__.py
中。我面临的问题是具有新结构的报告模块被导入两次,从而导致重新创建“registery”对象。因此,实际上没有注册网址。它从urls.py中的导入(如预期)加载一次,另一次由自动发现启动。我通过以下方式验证了这一点:
print hex(id(registery))
并发现它返回了2个不同的值。
我认为报告包将被导入一次,就像它只是一个模块一样。
如何防止它被加载两次?或者,我如何确保只有一个ReportsRegistery实例可以使用?
答案 0 :(得分:0)
Django两次导入模块的情况并不少见。这有两个原因:
经典的Django项目布局鼓励您在两个不同的位置将路径上的工作目录放在两次。这意味着您可以导入project.module
或app.project.module
的内容,这会混淆导入机制。
settings.py文件实际上已导入两次。
修正:
仔细检查所有导入是否使用相同的路径样式。
请勿从settings.py