django 1.7 gotcha-djano.setup()意外递归调用



所以,这一次很糟糕。我正在制定一个变通办法,但只是为了以防万一有更好的解决方案。而且,在弄清楚这一点之前,我花了几个小时,我也把它作为一个陷阱。

基本上,我想知道是否有聪明的方法可以避免递归调用django.setup().

我有3到4个批处理脚本,可以在独立模式下运行,也可以从celence运行。其中一个名为build_profiles.py

芹菜看到它们的方式(在tasks.py文件中):

from pssecurity.batch.build_profiles import 
    ProfileManager as MgrCls_profiles, 
    getOptParser as getOptParser_profiles

在Django 1.6中,这种安排很好(我不完全相信芹菜是启动潜在独立进程的最佳方式,但那是另一回事)。

当我尝试从命令行运行build_profiles.py时,它给出了一个AppRegistryNotReady错误。

没问题,我想,让我们将以下内容添加到build_profiles.py的顶部,根据https://docs.djangoproject.com/en/dev/ref/applications/#applications-故障排除

import django
django.setup()

然后Django就什么都没用了单元测试将不会运行,manager.py runserver将挂起。对独立批次的更改怎么会使我的系统停止?

事实证明,django.setup()发现了加载其任务的芹菜,如果其中一个最终完成了自己的django.setup.()…

为了在@jl-peyret的示例上进行构建,我使用了以下片段来触发文件顶部的异常,而不必包装模型访问,也不必知道将首先访问哪个模型:

from django.core.exceptions import AppRegistryNotReady
try:
    from django.apps import apps
    apps.check_apps_ready()
except AppRegistryNotReady:
    import django
    django.setup()

我的解决方法是捕获AppRegistryNotReady错误,并仅在需要时调用django.setup():

try:
    self.loadrdb(rdbname)
except AppRegistryNotReady:
    django.setup()
    self.loadrdb(rdbname)

下面的这个也起作用,但我认为尝试/捕获是更干净的

if __name__ == "__main__":
    import django
    django.setup()

我希望他们能让django.setup()变得足够聪明,能够识别出它已经运行过了,并在不做任何工作的情况下安静地返回。

最新更新