Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python django模型中的泛型关系是什么_Python_Django - Fatal编程技术网

Python django模型中的泛型关系是什么

Python django模型中的泛型关系是什么,python,django,Python,Django,有人在models.py中写了这个 documents = generic.GenericRelation(Document) 我想知道它与其他类型(如ForeignKey和OneToMany字段)有何不同 我还没有看到足够的文档 如果你发现了什么 但是,即使是在一开始,我也不明白contentype做什么以及为什么要使用它。想象一下,您的数据库中有各种对象(图像、视频、歌曲等),并且您希望向它们中的每一个添加关键字。但是,您希望有一个关键字表,用于管理具有关键字的所有对象的所有关键字。因此,

有人在models.py中写了这个

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
,并且您希望将具有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))
希望这能解释一下为什么需要泛型关系的概念。现在来看
一般关系
。使用上面的示例,假设您想要访问特定图像的所有关键字。您必须执行以下操作:

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是什么意思。你说的是哪种类型,在哪里?修改后的答案。希望这能更好地解释。谢谢,伙计,我现在明白了。事实上,我正在编辑现有的项目,它有所有的东西。