gpt4 book ai didi

python - django 模型中的通用关系是什么

转载 作者:行者123 更新时间:2023-11-30 23:40:07 25 4
gpt4 key购买 nike

有人在models.py中写了这个

documents = generic.GenericRelation(Document)

我想知道它与 ForeignKeyOneToMany 字段等其他类型有何不同。

我还没有看到足够的文档

如果发现什么here

但即使一开始我也不明白 contentype 的作用以及为什么使用它。

最佳答案

假设您的数据库中有各种对象(图像、视频、歌曲等),并且您想为每个对象添加关键字。但是,您希望有一个关键字表来管理所有具有关键字的对象的所有关键字。所以模型看起来像这样:

class Image(models.Model):
# ...

class Video(models.Model):
# ...

class Keyword(models.Model):
keyword = models.CharField(max_length=64)

因此有了模型,您需要以某种方式将关键字连接到其他对象。为此,您需要使用多对多关系:

class KeywordItem(models.Model):
keyword = models.ForeignKey('Keyword')
image = models.ForeignKey('Image')

然而,这不起作用,因为这只会允许您添加图像的关键字,但是您还需要视频等的关键字。换句话说,这种方法的问题是它限制将关键字链接到具体表,图像表。因此,我们的想法不是这样做,而是链接到任何表,然后只需指定要链接的表:

class KeywordItem(models.Model):
keyword = models.ForeignKey('Keyword')
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
object = generic.GenericForeignKey('content_type', 'object_id')

content_type 指定您要链接的表,object_id 指定您要链接的表中行的主键。

现在的问题是如何指定您链接到哪个表?一种解决方案是对选择进行硬编码(图像为 1,视频为 2 等),但这很容易出错,因为必须对其进行维护。事实证明,Django 通过使用 content types framework 解决了这个问题。 。发生的情况是,当您执行 syncdb 时,Django 会为项目中的每个表/模型分配一个唯一的编号。对我来说,更容易将其视为表类型 id(假设为表 id,因为表本身没有 id)。所以以后可以用这个数字来引用具体的表格。

然后,如果图像内容类型(表类型 ID)为 1,并且您希望将 pk 7 的关键字链接到 pk 11,您可以通过以下方式做到这一点:

KeywordItem.objects.create(keyword_id=7,
content_type_id=1,
object_id=11)

# or using Django magic (this automatically figures out the content type):
KeywordItem.objects.create(keyword_id=7,
object=Image.objects.get(pk=11))

希望这能解释一下为什么您可能需要通用关系的概念。现在介绍GenericRelation。使用上面的示例,假设您想要访问特定图像的所有关键字。您必须执行以下操作:

img = Image.object.get(...)
img_type = ContentType.objects.get_for_model(img)
img_keywords = KeywordItem.objects.filter(content_type_id=img_type,
object_id=img.pk)

然而,这看起来并不干净,这就是 GenericRelation 有用的原因。它使得访问反向泛型关系变得非常容易。为此,您必须将以下字段添加到 Image 模型中:

class Image(models.Model):
# ...
keywords = generic.GenericRelation('KeywordItem')

现在,您只需执行以下操作即可访问关键字:

Image.object.get(...).keywords.all()

注意事项

通用外键是一件棘手的事情,尤其是在 Django 中,因为语法有些棘手。如果您是 Django 的初学者,我不建议您对它们做任何事情,直到您熟悉 Django 中的外键以及 Django 提供的所有“神奇”功能(例如 lated_name 参数)。一旦理解了这一点,通用外键将更容易理解和使用。

关于python - django 模型中的通用关系是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12888949/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com