2014-11-04 8 views
5

Quindi, questo era un doozy. Sto mettendo in atto una soluzione alternativa, ma la sto mettendo nel caso in cui esista una soluzione migliore. E, dopo aver passato parecchie ore prima di capirlo, lo sto anche mettendo in evidenza.django 1.7 gotcha - django.setup() chiamate di ricorsione accidentali

Fondamentalmente, mi chiedevo se ci sono modi intelligenti per evitare le chiamate ricorsive a django.setup().

Ho 3 o 4 script batch che posso eseguire sia in modalità standalone che da sedano. Uno di loro si chiama build_profiles.py

Il modo sedano arriva a vederli (in una delle tasks.py) file:

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

In Django 1.6 questa disposizione ha funzionato bene (io non sono del tutto convinto sedano è il modo migliore per avviare processi potenzialmente autonomi ma questa è un'altra storia).

Quando ho provato a eseguire build_profiles.py dalla riga di comando, ha generato un errore AppRegistryNotReady.

Nessun problema, ho pensato, aggiungiamo il seguente in cima build_profiles.py, come da https://docs.djangoproject.com/en/dev/ref/applications/#applications-troubleshooting

import django 
django.setup() 

E poi niente funzionava più con Django. I test di unità non verrebbero eseguiti, manager.py runserver si bloccava. In che modo un passaggio a un lotto indipendente potrebbe arrestare il mio sistema?

scopre che django.setup() scopre sedano che carica i suoi compiti, e se una di queste finisce per fare la propria django.setup() ...

+0

Grazie per aver pubblicato la soluzione. Tuttavia, le pratiche editoriali su SO sono tali che le domande dovrebbero contenere solo domande e le soluzioni dovrebbero essere formalmente pubblicate come risposte. Invia la soluzione alternativa come risposta formale e rimuovila dalla tua domanda. – Louis

+0

Forse questo aiuta: http://stackoverflow.com/a/32095654/633961 – guettli

risposta

2

Per creare un bit nell'esempio di @ jl-peyret, ho utilizzato il seguente snippet per attivare l'eccezione nella parte superiore del file senza dover avvolgere l'accesso al modello e sapere quale dei modelli sarà accessibile primo:

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

mia soluzione era quella di intercettare l'errore e AppRegistryNotReady chiamo django.setup() solo se necessario:

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

questo seguito ha lavorato anche, ma penso che il try/catch è più pulita

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

Vorrei hanno fatto idempotente, con Django .setup() è abbastanza intelligente da riconoscere che è già stato eseguito e torna tranquillamente senza fare alcun lavoro.

Problemi correlati