python - 这里导入错误的具体原因是什么?

标签 python django

大家好!

关于我遇到的一件事的简单问题,我理解了这个问题,但无法弄清楚为什么?

不仅我不知道例如model1是否必须具有model2model2ForeignKey使用 ManyToManyFieldmodel1(困惑)。

假设我们有两(2)个模型文件三(3)个类模型app1.models.py,其中[Model1ModelA] 和 app2.models.py 以及 [Model2]。

app1.models.py

from app2.models import Model2

class Model1(models.Model):
    field1 = models.ForeignKey(Model2)

app2.models.py

from app1.models import ModelA

 class Model2(models.Model):
    field2 = models.ForeignKey(ModelA)

这肯定会引发错误ImportError

但如果我这样做:

class Model1(models.Model):
    field1 = models.ForeignKey("app2.Model2")
<小时/>
class Model2(models.Model):
    field2 = models.ForeignKey("app1.ModelA")

这会很好用

到底为什么?

我知道我可以在所需的文件中创建模型,但我想要的是了解为什么一个模型有效,而另一个模型无效。

谢谢!

最佳答案

import 语句实际上是可执行语句。如果您要求导入foo.bar.qux,那么Python将首先检查它是否已经导入该文件(在sys.modules中)。

如果尚未导入该模块,它将首先搜索该模块对应的文件。如果找不到该文件,我们会得到一个ImportError,在其他情况下,Python 将打开相应的文件,并“导入它”。

导入意味着它将执行文件中的所有语句(从上到下)。但现在想象一下,您必须保存彼此需要的文件。在这种情况下,文件 A 需要(完全)导入文件 B。但是 B 需要(完全)导入文件 A。没有办法解决这个问题:因为文件末尾可能有语句,可以更改 class 定义等。但是我们已经达到了 import 语句,这是模块完全加载的“契约(Contract)”。所以这基本上是“先有鸡还是先有蛋”的问题。

但是,我们可以通过推迟链接来解决此类循环导入。而不是将引用传递给类。例如,我们可以传递某种 token (Django 使用字符串,但可能有不同的方式)。现在字符串不会引入问题,因为在我们开始解释之前,Python 的“内置库”已经加载到内存中。

所有模型类加载到内存后,Django 将执行“链接”阶段。加载阶段结束后,所有 models.py 文件都会加载到内存中,因此现在我们可以用对类的引用替换字符串。因此,Django 基本上通过推迟将 ForeignKey 链接到真实的类对象来解决该问题。

关于python - 这里导入错误的具体原因是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50686164/

相关文章:

python - Django key 泄露

python - 如何使用 3x3 内核平滑图像

php - 如何以编程方式编写 nslookup?

django - Django 中如何发送电子邮件

python - 如何检查 Django 中多对多字段的类型?

python - Django 结果返回绝对 URL

python - 在 Django ModelForm 字段中包含自动生成的主键

django - TurnKey Django -- 如何将 Django 升级到 1.4

python - 尝试分配给我同时就地创建的字符串时出现错误 'can' t assign to operator'

python - 在音频文件开始处测量静音长度(wav)