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

时间:2014-11-04 21:26:47

标签: django

所以,这个是一个很糟糕的。我正在采取一种解决方法,但只是将其解决,以防有更好的解决方案。并且,在花了几个小时才弄明白之前,我也把它作为一个问题。

基本上,我想知道是否有巧妙的方法可以避免对django.setup()进行递归调用。

我有3个或4个批处理脚本,我可以在独立模式或芹菜中运行。其中一个名为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错误。

没问题,我想,让我们按照https://docs.djangoproject.com/en/dev/ref/applications/#applications-troubleshooting

将以下内容添加到build_profiles.py的顶部
import django
django.setup()

然后Django再没有任何工作了。单元测试无法运行,manager.py runserver会挂起。如何改变独立批处理会使我的系统停止运行?

原来django.setup()发现芹菜加载它的任务,如果其中一个最终做了自己的django.setup()......

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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

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

这下面也有效,但我认为try / catch更清晰

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

我希望他们是幂等的,django.setup()足够聪明,能够认识到它已经运行并且在没有做任何工作的情况下安静地返回。