Django 1.7 getcha - django.setup () random recursion calls

So this one was doozy. I use a workaround, but just put this in case there is a better solution. And after spending a few hours to figure it out, I also do it as prey.

Basically, I was wondering if there are smart ways to avoid recursive calls to django.setup ().

I have 3 or 4 batch scripts that can be run offline or from celery. One of them is called build_profiles.py

How celery gets them (in one of the tasks.py files):

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

In Django 1.6, this scheme worked just fine (I'm not completely convinced that celery is the best way to run potentially autonomous processes, but that's a different story).

When I tried to run build_profiles.py from the command line, it gave the AppRegistryNotReady error.

No problem, I thought, add the following to the top of build_profiles.py, according to https://docs.djangoproject.com/en/dev/ref/applications/#applications-troubleshooting

 import django django.setup() 

And then nothing worked with Django. single tests were not performed, maintaining the manager.py server. How can I go to an autonomous party to stop my system?

It turns out that django.setup () detects a celery that loads its tasks, and if one of them finishes executing its own django.setup () ...

+5
source share
2 answers

To create a bit in the example using @ jl-peyret, I used the following snippet to throw an exception at the top of the file without having to exchange access to the model and know which of these models will be available first

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

My workaround was to catch the AppRegistryNotReady error and call django.setup () only if necessary:

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

this below also worked, but I think try / catch is cleaner.

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

I would like them to make idempotent, with django.setup () smart enough to realize that it is already running and is returning quietly without doing any work.

+1
source

Source: https://habr.com/ru/post/1206201/


All Articles