如何定义多对多表

时间:2012-07-26 15:29:52

标签: django many-to-many

我在理解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_idcategory_id)。

所以我的问题是 - 这是正常的吗?或者我是否以某种方式错误地定义了多对多字段?我的下一个问题是如何将所有category_ids与特定GlobalPart相关联?

2 个答案:

答案 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

的链接