2016-04-05 4 views
1

models.py:Wie vermeidet man zyklischen Import in diesem Fall?

from core.tasks import hello 

class Foo(models.Model): 
    def save(self, force_insert=False, force_update=False, using=None, update_fields=None): 
     hello.delay() 
     super(Foo, self).save(force_insert, force_update, using, update_fields) 

tasks.py:

from core.models import Foo 

@shared_task 
def hello(): 
    Foo.objects.create() 

-Code verursacht oben ImportError: cannot import name Foo.

Wie vermeiden Sie diese Situationen und folgen Sie den Best Practices?

+5

Sie kann immer auf Funktionsebene importiert werden. –

+0

@AshwiniChaudhary: Import auf Funktionsebene bedeutet? –

+0

Es könnte bedeuten, dass es möglich ist, die Importanweisung in die Funktionsdefinition zu verschieben. – zezollo

Antwort

1

Sie entweder das Modell auf Funktionsebene importieren:

@shared_task 
def hello(): 
    from core.models import Foo 
    Foo.objects.create() 

Oder Sie können Djangos get_model() Funktion zu importieren Modelle in eine saubere Art und Weise verwenden:

from django.apps import apps 

@shared_task 
def hello(): 
    foo_model = apps.get_model('core', 'Foo') 
    # 'core' is appname and 'Foo' is model name 
    foo_model.objects.create() 
1

Sie können innerhalb der Funktionen importieren, und das wird Sie Code funktioniert:

@shared_task 
def hello(): 
    from core.models import Foo 
    Foo.objects.create() 

jedoch 99% der Zeit ich in dieses Problem lief erkannte ich, dass es ein logischer Fehler in meinem Code war nachdem ich genug nachgedacht habe. Disclaimer: Ich habe fast keine Erfahrung mit Django.

Wenn A benötigt B und B braucht A, gibt es in der Regel etwas kaputt. Die meisten der Zeit, ist das Problem einer der folgenden:

  • A und B logisch gehören toghether und sollte
  • A und B sind logisch discting genug, um in dem selben Modul zusammengefügt werden, aber es gibt gemeinsame Funktionalität, die tut nicht auf etwas anderes von A oder B abhängen, so dass es möglich ist, es in C zu abstrahieren und es von den anderen beiden zu importieren.
  • A hat eine falsche Abhängigkeit in B, weil AB überhaupt nicht benötigt.

In Ihrem Fall würde ich sagen, dass es die dritte Option ist. tasks muss eindeutig auf models verlassen werden. Aber braucht modelstasks überhaupt? tun Sie einfach von models, was Sie brauchen. Zum Beispiel:

class Foo(models.Model): 
    def save(self, force_insert=False, force_update=False, using=None, update_fields=None): 
     Foo.objects.create() 
     super(Foo, self).save(force_insert, force_update, using, update_fields) 
+0

tasks.py haben komplizierter Code und Logik - 'Foo.objects.create()' nur zum Beispiel –

+0

Sie können versuchen, Ihren Code in eine Methode zu packen, zum Beispiel 'Foo.do_the_complicated_thing', und rufen Sie dann von der' ' Aufgaben ". – bgusach

Verwandte Themen