我在理解Django中的多对多字段时遇到了一些麻烦。
当我创建多对多字段时,例如:
class GlobalPart (Models.model):
...
category_id=models.ManyToManyField(Category, related_name = 'globalpart')
...
和
class Category (Model.model):
...
category = models.CharField(max_length=250)
...
我注意到除了appname_globalpart_category_id
模型的appname_globalpart
表之外,它还创建了一个名为GlobalPart
的新表。
我想知道的是,如何定义该表中的字段类型。我想是的
那里至少应该有一个外键来关联这些字段。但相反,表有主键,其他字段是整数(globalpart_id
和category_id
)。
所以我的问题是 - 这是正常的吗?或者我是否以某种方式错误地定义了多对多字段?我的下一个问题是如何将所有category_ids
与特定GlobalPart
相关联?
答案 0 :(得分:1)
您认为外键是什么?它是一个包含等于ID的字段 - 通常是主键 - 在“外部”表中。如果另一个表具有整数键,就像大多数Django表那样,那么外键字段也将是整数类型。
此外,Django创建约束,以便数据库强制ID确实引用外表中的有效值。根据您的数据库,这些可能会也可能不会显示为字段定义的一部分。
答案 1 :(得分:1)
(1)简答:是的,这是正常的。
答案很长:ManyToMany表需要Category和GlobalPart表的外键。严格来说,这两个外键应该足够了。你在那里看到的额外PK只是为了django魔法。如果您自己手动定义多对多表,那么您只能在该表中使用这两个外键。但是如果你让django为你做(通过使用ManyToManyField)你得到这个额外的PK
(2)我建议将模型字段category_id更改为类别:
class GlobalPart (Models.model):
categories=models.ManyToManyField(Category, related_name = 'globalpart')
这是因为,ManyToManyFields很好地指向"很多"项目。该字段不是指"一个" category_id,它指所有相关类别。因此,在命名时,相应地命名它是很自然的。
至于访问所有类别,您可以通过访问"类别"属性。假设您的对象实例名为global_part,您可以访问如下类别:
categories = global_part.categories.all()
您可以使用filter()或exclude(),而不是all(),就像查询模型时一样。
以下是相关django docs
的链接