Hello Awesome People!
关于我遇到的事情并理解问题但却无法弄清楚原因的简单问题?
我不仅不知道例如model1
是ForeignKey
到model2
还是model2
ManyToManyField
到model1
(困惑)。
假设我们有两(2)个模型文件和三(3)类模型,app1.models.py
[Model1
,{{ 1}}]和ModelA
与[app2.models.py
]。
app1.models.py
Model2
app2.models.py
from app2.models import Model2
class Model1(models.Model):
field1 = models.ForeignKey(Model2)
这肯定会引发错误from app1.models import ModelA
class Model2(models.Model):
field2 = models.ForeignKey(ModelA)
,
但如果我这样做:
ImportError
class Model1(models.Model):
field1 = models.ForeignKey("app2.Model2")
这样可以正常使用
为什么到底?
我知道我可以在所需的文件中创建模型,但我想要的是理解为什么一个有效,而不是另一个。
谢谢!
答案 0 :(得分:2)
import
语句实际上是可执行语句。如果您要求import foo.bar.qux
,那么Python将首先检查它是否已导入该文件(在sys.modules
中)。
如果尚未导入该模块,它将首先执行搜索与模块对应的文件。如果找不到文件,我们会得到一个ImportError
,在另一种情况下,Python会打开相应的文件,并且#34;导入它"。
导入意味着它将执行文件中的所有语句(从上到下)。但现在想象你必须要有彼此需要的文件。在这种情况下,文件A
需要(完全)导入文件B
。但B
要求(完全)导入文件A
。没有办法解决这个问题:因为文件末尾可能有语句,这会改变class
定义等等。但是我们已经达到import
语句,这是一个&#34 ;合同"该模块已完全加载。所以这基本上是" 鸡与鸡蛋" -problem。
然而,我们可以通过推迟链接来解决这种循环导入。而不是将引用传递给类。例如,我们可以传递某种令牌(Django使用字符串,但可能有不同的方式)。现在字符串不会引入问题,因为在我们开始解释之前,"内置库" Python已经加载到内存中了。
将所有模型类加载到内存后,Django将执行" 链接"相。在加载阶段之后,所有models.py
文件都被加载到内存中,所以现在我们可以用对类的引用替换字符串。所以Django基本上通过推迟将ForeignKey
s链接到真实类对象来解决问题。
答案 1 :(得分:1)
符号
field1 = models.ForeignKey(Model2)
表示已经创建了“Model2”。但是python在一个序列中创建了两个对象。当python创建ModelA时会遇到此错误,而ModelA试图指向尚未存在的ModelB。 您可以使用
解决此问题field1 = models.ForeignKey("app2.Model2")
你也可以在Django documentation
中看到这个如果需要在尚未定义的模型上创建关系,可以使用模型的名称,而不是模型对象本身。