循环进口动机

时间:2018-10-08 10:57:04

标签: django django-models

我很难理解为什么Django / python不允许循环导入。无需使用data_I_care_about = dict(zip(df.col1, df.col2)) #or other_data = df.col3.values.tolist() 然后硬编码模型的标签和名称,是否有解决方法?

假设我有2个模型apps.get_modelA,其中B的FK为A,而B的属性基于B

模型A

A

模型from main import B field = models.ForeignKey(B, default=None)

B

解决该问题的唯一方法是上面的代码,如果我尝试导入 # from main import A // this does not work @property def last_used(self): A = apps.get_model(app_label='main', model_name= 'A') 并使用A则会遇到A.objects.filter错误。

我的问题是,当我重构代码时,查找所有这些硬编码的模型名称变得很麻烦。

这是一个不好的设计,我应该完全改变模型背后的逻辑吗?

2 个答案:

答案 0 :(得分:3)

Python不允许循环导入,因为它会带来麻烦。如果您写:

# module2.py
import module

Python将首先读取module.py并定义类,函数等。

但是如果在module中显示:

# module.py
import module2

这不能解决:由于module2首先需要module,而module首先需要module2

由于经常发生ForeignKey这类循环导入的情况,因此Django添加了一种方便的方式来指定模型:您可以使用字符串常量。例如:

# app1/models.py

class Model1(models.Model):
    model2 = ForeignKey('app2.Model2', on_delete=models.CASCADE)

而在app2/models.py中,我们可以这样写:

# app2/models.py

class Model2(models.Model):
    model1 = ForeignKey('app1.Model1', on_delete=models.CASCADE)

因此您不需要导入模型,可以使用字符串文字作为标识符,而Django将“打结”。

如果需要循环引用,可以在 函数中创建导入,例如:

def some_module(args):
    from main import A
    # ...
    pass

这不会不会导致循环导入(除非您立即调用当然是该函数),否则import将被推迟直到您将执行该函数。

答案 1 :(得分:2)

您完全不需要在B内部导入A。由于A具有指向B的外键,因此可以使用反向关系

@property
def last_used(self):
    return self.a_set.last()