0

我有一个 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包中。我面临的问题是具有新结构的报告模块被导入两次,从而导致重新创建“注册”对象。因此,实际上没有注册任何网址。它从 urls.py 中的导入加载一次(如预期的那样),另一次由自动发现启动。我已经通过以下方式验证了这一点:

print hex(id(registery))

并发现它返回了 2 个不同的值。

我认为报告包将被导入一次,就像它只是一个模块一样。

如何防止它被加载两次?或者我如何确保我们只有一个 ReportsRegistery 实例可以使用?

4

1 回答 1

0

Django 两次导入模块并不少见。有两个原因:

  1. 经典的 Django 项目布局鼓励您将工作目录放在路径上的两个不同位置两次。这意味着您可以导入一些东西 asproject.module或 as app.project.module,这会混淆导入机制。

  2. settings.py 文件实际上被导入了两次。

修复:

  1. 仔细检查所有导入是否使用相同样式的路径。

  2. 不要从 settings.py 导入你的模块

于 2013-02-11T16:18:02.577 回答