2016-04-05 11 views
1

models.py:この場合、周期インポートを回避するにはどうすればよいですか?

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() 

コード上記ImportError: cannot import name Fooの原因となります。

このような状況を回避し、ベストプラクティスに従う方法を教えてください。

+5

ます常に機能レベルでインポートできます。 –

+0

@AshwiniChaudhary:機能レベルでのインポートは意味ですか? –

+0

importステートメントを以下の関数定義に移動することが可能である可能性があります。 – zezollo

答えて

1

あなたは、関数レベルでモデルをインポートすることができ、次のいずれか

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

たり、よりクリーンな方法でモデルをインポートするために、Djangoのget_model()機能を使用することができます。

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

あなたが関数の内部でインポートすることができ、そしてそれはあなたのコードの作業を行います。

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

しかし、私は自分のコード内の論理エラーがあったことに気づき、この問題に遭遇した回数の99%を十分に思考した後に。免責事項:私はdjangoの経験はほとんどありません。

AにはBが必要であり、BにはAが必要ですが、一般には何か壊れています。時間のほとんどは、問題は、これらのいずれかです。

  • ABは、論理的にtoghether属し、同じモジュールにマージされなければならない
  • ABが論理的に十分disctingされていますが、ない一般的な機能がありますAまたはBから別のものに依存せず、Cに抽象化して他の2つからインポートすることができます。
  • ABに偽の依存関係があります。AにはBがまったく必要ないためです。

あなたの場合、私はそれが第3の選択肢であると言います。 tasksは明らかにmodelsに依存する必要があります。しかし、modelsにはtasksが必要ですか?必要なものをmodelsからどうぞ。例えば:

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はもっと複雑なコードとロジックを持っています - 例えば 'Foo.objects.create()'だけです –

+0

あなたのコードをメソッドにパックすることができます。たとえば、 'Foo.do_the_complicated_thing'のようにして、タスク '。 – bgusach

関連する問題