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

时间:2016-06-01 13:07:12

标签: django django-models many-to-many django-orm

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

meal-menu schema

简而言之,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:

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

1 个答案:

答案 0 :(得分:2)

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

此处用户可能有多个MenuItem,但您还需要与selectedlike属性相关的属性,但将这2个属性移动到任一模型都是好的,因此through是最好的解决方案。

查看关于through definition and example的django doc。