我不明白为什么人们用两种方式写外键,这的目的是什么?它们是相同还是不同?
我注意到有些人这样写道:
author = models.ForeignKey(Author, on_delete=models.CASCADE)
有些人这样写:
author = models.ForeignKey('Author', on_delete=models.CASCADE)
这些之间有什么区别?这样写有什么特殊目的吗?还是两者都一样?
答案 0 :(得分:2)
这些之间有什么区别?这样写有什么特殊目的吗?还是两者都一样?
它们都导致相同的链接,是的。字符串稍后将被“解析”,最终ForeignKey
将指向Author
模型。
但是,如果需要定义目标模型,则有时有时仅使用字符串进行引用。例如,对于循环引用。
例如,假设您定义如下关系:
class Author(models.Model):
name = models.CharField(max_length=128)
favorite_book = models.ForeignKey(Book, null=True, on_delete=models.SET_NULL)
class Book(models.Model):
title = models.CharField(max_length=128)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
这里Book
指的是Author
,而Author
指的是Book
。但是,由于在构造Book
时并未构造ForeignKey
类,因此将得到NameError
。
在定义Author
之后,我们不能再定义Book
,因为那样的话,我们在构造Author
之前就先参考了{{1} }。
但是我们可以在这里使用字符串,避免使用循环引用,例如:
NameError
通过使用字符串,对于Python解释器来说是很好的,因为您不使用尚未定义的标识符,并且Django将在加载模型时将字符串替换为对相应模型的引用
documentation on a ForeignKey
[Django-doc]:
如果需要在尚未定义的模型上创建关系,则可以使用模型的名称,而不是模型对象本身(...)
如果模型是在另一个应用程序中定义的,则可以使用class Author(models.Model):
name = models.CharField(max_length=128)
favorite_book = models.ForeignKey('Book', null=True, on_delete=models.SET_NULL)
class Book(models.Model):
title = models.CharField(max_length=128)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
来引用它。
答案 1 :(得分:1)
假设您已将模型布置如下:
models/
__init__.py
model_a.py
model_b.py
当您的应用程序具有很多模型并且希望更好地组织代码时,这是常见的布局。现在说ModelA
有一个ModelB
的外键,而ModelB
有一个ModelA
的外键。您不能同时导入两个文件,因为要进行循环导入。
通过字符串引用另一个模型使您可以“延迟”引用尚未加载的另一个模型,这解决了循环导入的问题