如何在 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
定义为User
和MenuItem
之间m2m 关系的through
模型。 through
模型主要用于在m2m关系之间定义一些额外的属性时使用。
这里一个用户可以有多个MenuItem
s,但你也希望selected
和like
属性与关系一起出现,但是将这两个属性移动到任一模型都不好,因此@987654330 @ 是最好的解决方案。
查看关于 through
definition and example 的 django 文档。
【讨论】:
这很有帮助!根据上面@GertjanBrouwer 的评论,显式through
模型是否优于隐式多对多字段?
好吧,正如我所提到的,如果你有 m2m 关系附带的附加属性,只使用through
,如果你只有一个纯 m2m 关系,那么through
是多余的。但是,您还应该注意,无论您是否定义through
,django 总是会创建一个中间数据库表来链接这两个表。以上是关于如何在 Django 中创建和链接多对多表?的主要内容,如果未能解决你的问题,请参考以下文章