在这种情况下如何避免循环导入?

时间:2016-04-05 14:17:26

标签: python

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

如何避免这种情况并遵循最佳做法?

2 个答案:

答案 0 :(得分:1)

您可以在函数内部导入,这将使代码工作:

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

然而,99%的时间我遇到了这个问题,我意识到在我的代码经过足够的思考后,我的代码中存在逻辑错误。免责声明:我几乎没有django的经验。

如果A需要BB需要A,则通常会出现问题。大多数时候,问题就是其中之一:

  • AB在逻辑上属于其他并且应该合并到同一个模块中
  • AB在逻辑上足够分散,但有一些共同的功能不依赖AB中的任何其他功能,因此可以抽象它进入C并从其他两个进口。
  • AB有假依赖,因为A根本不需要B

在你的情况下,我会说这是第三种选择。 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)

答案 1 :(得分: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()