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

django 1.7 gotcha-django.setup()意外递归调用,django,Django,所以,这一次真是太棒了。我正在做一个变通方案,但只是把它放出来,以防有更好的解决方案。而且,我花了几个小时才弄明白这一点,我也把它作为一个陷阱 基本上,我想知道是否有聪明的方法可以避免对django.setup()的递归调用 我有3或4个批处理脚本,可以在独立模式下运行,也可以从芹菜中运行。其中一个名为build_profiles.py 芹菜看到它们的方式(在tasks.py文件之一中): 在Django 1.6中,这种安排效果很好(我不完全相信芹菜是启动潜在独立流程的最佳方式,但这是另一回事)

所以,这一次真是太棒了。我正在做一个变通方案,但只是把它放出来,以防有更好的解决方案。而且,我花了几个小时才弄明白这一点,我也把它作为一个陷阱

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

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

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

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

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

没问题,我想,让我们按照

然后Django就不再工作了。单元测试将无法运行,manager.py runserver将挂起。对独立批处理的更改如何使我的系统停止


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

我的解决方法是捕获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()足够聪明,可以识别它已经运行过,并且可以在不做任何工作的情况下安静地返回。

以@jl peyret的示例为基础,我使用了以下代码片段触发文件顶部的异常,而无需包装模型访问并知道将首先访问哪个模型:

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

感谢您发布您的解决方案。然而,SO的编辑实践是这样的:问题应该只包含问题,解决方案应该作为答案正式发布。请将您的解决方法作为正式答案发布,并将其从您的问题中删除。也许这有助于:
if __name__ == "__main__":
    import django
    django.setup()
from django.core.exceptions import AppRegistryNotReady
try:
    from django.apps import apps
    apps.check_apps_ready()
except AppRegistryNotReady:
    import django
    django.setup()