Python django模型中的泛型关系是什么
有人在models.py中写了这个Python django模型中的泛型关系是什么,python,django,Python,Django,有人在models.py中写了这个 documents = generic.GenericRelation(Document) 我想知道它与其他类型(如ForeignKey和OneToMany字段)有何不同 我还没有看到足够的文档 如果你发现了什么 但是,即使是在一开始,我也不明白contentype做什么以及为什么要使用它。想象一下,您的数据库中有各种对象(图像、视频、歌曲等),并且您希望向它们中的每一个添加关键字。但是,您希望有一个关键字表,用于管理具有关键字的所有对象的所有关键字。因此,
documents = generic.GenericRelation(Document)
我想知道它与其他类型(如ForeignKey
和OneToMany
字段)有何不同
我还没有看到足够的文档
如果你发现了什么
但是,即使是在一开始,我也不明白contentype做什么以及为什么要使用它。想象一下,您的数据库中有各种对象(图像、视频、歌曲等),并且您希望向它们中的每一个添加关键字。但是,您希望有一个关键字表,用于管理具有关键字的所有对象的所有关键字。因此,模型将类似于:
class Image(models.Model):
# ...
class Video(models.Model):
# ...
class Keyword(models.Model):
keyword = models.CharField(max_length=64)
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)
因此,有了这些模型,您需要以某种方式将关键字连接到其他对象。为此,您需要使用多对多关系:
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\u type
指定要链接到哪个表,object\u id
指定要链接到的表中的行的主键
现在的问题是如何指定要链接到哪个表?一种解决方案是对选项进行硬编码(图像是1
,视频是2
,等等),但这很容易出错,因为必须对其进行维护。事实证明,Django通过使用解决了这个问题。当您执行syncdb
时,Django会为项目中的每个表/模型分配一个唯一的编号。对我来说,更容易将其视为表类型id(假设为表id,因为表本身没有id)。所以这个数字以后可以用来参考特定的表
然后,如果图像内容类型(表类型id)为1
,并且您希望将具有pk7
的关键字链接到具有pk11
的图像,则可以通过以下方式执行此操作:
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))
希望这能解释一下为什么需要泛型关系的概念。现在来看一般关系。使用上面的示例,假设您想要访问特定图像的所有关键字。您必须执行以下操作:
class Image(models.Model):
# ...
class Video(models.Model):
# ...
class Keyword(models.Model):
keyword = models.CharField(max_length=64)
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)
然而,这看起来并不干净,这就是为什么generirelation
很有用的原因。它使访问反向泛型关系变得非常容易。为此,您必须将以下字段添加到图像
模型中:
class Image(models.Model):
# ...
keywords = generic.GenericRelation('KeywordItem')
现在,您只需执行以下操作即可访问关键字:
Image.object.get(...).keywords.all()
注意事项
通用外键是一项棘手的工作,尤其是在Django中,由于语法有些棘手。如果您是Django的初学者,我建议您在使用Django外键和Django提供的所有“魔力”(例如,相关的_name
参数)之前不要使用它们。一旦你明白了这一点,通用外键将更容易理解和使用。谢谢你的朋友,这真的向我解释了一切。希望Djnago的人在文档中包含这种类型的示例:)。有一件事我不清楚。这行图像表类型id为1是什么意思。你说的是哪种类型,在哪里?修改后的答案。希望这能更好地解释。谢谢,伙计,我现在明白了。事实上,我正在编辑现有的项目,它有所有的东西。