如何在 Django 中创建和链接多对多表?

Posted

技术标签:

【中文标题】如何在 Django 中创建和链接多对多表?【英文标题】:How can I create and link many-to-many tables in Django? 【发布时间】:2016-09-30 21:03:24 【问题描述】:

我正在一个 Django 应用程序中实现以下架构,但我是 Django 的 ORM 的新手:

简而言之,一个 DayMenu 列出了多个 MenuItem。 (MenuItem 只是 DayMenu 和 Meal 之间的多对多关系。)每个用户从 DayMenu 中选择一个 MenuItem。 (此选项表示为 UserItemChoice。)

在我们的初稿models.py(如下)中,MenuItem 被定义为 DayMenu 模型上的多对多字段。

from __future__ import unicode_literals

from django.db import models

# Create your models here.

class Meal(models.Model):

    # field options: diet
    MEAT = "MEAT"
    VEGETARIAN = "VEGET"
    HALAAL = "HALAA"

    DIET_CHOICES = (
        (MEAT, "Meat"),
        (VEGETARIAN, "Vegetarian"),
        (HALAAL, "Halaal"),
    )

    # field options: type
    FREE = "FREE"
    PAID = "PAID"
    SKIP = "SKIP"

    TYPE_CHOICES = (
        (FREE, "Free"),
        (PAID, "Paid"),
        (SKIP, "Skip"),
    )

    # fields
    cost = models.IntegerField(default=10)
    description = models.CharField(max_length=120)
    diet = models.CharField(max_length=5, choices=DIET_CHOICES)
    type = models.CharField(max_length=5, choices=TYPE_CHOICES)


class DayMenu(models.Model):

    # fields
    date = models.DateField()
    locked = models.BooleanField(default=False)
    item = models.ManyToManyField(Meal)  # TODO: confirm (replaces MenuItem in schema)


# class UserItemChoice(models.Model):
#
#     # fields
#     user = models.CharField()  # FIXME
#     menuitem = models.CharField()  # FIXME
#     selected = models.BooleanField(default=False)
#     like = models.NullBooleanField(default=None)

鉴于以下情况,我们如何定义 UserItemChoice:

它本身就是一个多对多的关系 它链接到多对多字段而不是(显式)模型 它将(理想情况下?)是内置用户表上的多对多字段

【问题讨论】:

多对多关系存在本质上的问题,您只需要创建一个连接表来促进这种关系。 en.wikipedia.org/wiki/Associative_entity @GertjanBrouwer 您是否建议我们将 MenuItem 明确指定为 through 模型? (正如@ShangWang 对 UserItemChoice 的建议) 这是一样的想法耶.. 【参考方案1】:

我认为您想要的是将UserItemChoice 定义为UserMenuItem 之间m2m 关系的through 模型。 through模型主要用于在m2m关系之间定义一些额外的属性时使用。

这里一个用户可以有多个MenuItems,但你也希望selectedlike属性与关系一起出现,但是将这两个属性移动到任一模型都不好,因此@987654330 @ 是最好的解决方案。

查看关于 through definition and example 的 django 文档。

【讨论】:

这很有帮助!根据上面@GertjanBrouwer 的评论,显式through 模型是否优于隐式多对多字段? 好吧,正如我所提到的,如果你有 m2m 关系附带的附加属性,只使用through,如果你只有一个纯 m2m 关系,那么through 是多余的。但是,您还应该注意,无论您是否定义through,django 总是会创建一个中间数据库表来链接这两个表。

以上是关于如何在 Django 中创建和链接多对多表?的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 中加入多对多表

十一 .Django 多对多表ManyToManyField (ORM)

Django中ORM多对多表的操作

创建多对多表关系的三种方式

django学习-34.多对多表关系对应的完整业务操作

Django