如何在不更改记录对象的情况下进行多对多链接

时间:2019-08-31 15:15:46

标签: django django-models

我觉得这里缺少一些基本知识,但我无法弄清楚。我将给出一个简化示例,说明我要实现的目标。以这个典型的餐厅为例。

如果我有披萨表,其中填有披萨名称的记录。另一个表是记录比萨馅料。他们有多对多的关系。如果客户订购带有“意大利辣味香肠”和“蘑菇”的“ 2馅料”,则在后端,一些脚本将获得“ 2馅料”比萨饼对象,并获得两个馅料对象,然后链接/添加/关联它们。这样pizza.toppings.all()将返回两个开头的QuerySet。

如果其他顾客在订购后不久又订购了完全相同的披萨。先前添加的浇头将已经链接到该披萨对象。显然,在每次下订单后清除关系是不切实际的。


##Model

class Pizza(models.Model):

    name = models.CharField(max_length=30)
    toppings = models.ManyToManyField('Topping', related_name='pizzas'))

    def __str__(self):
        return self.name


class Topping(models.Model):

    name = models.CharField(max_length=30)

    def __str__(self):
        return self.name

class Order(models.Model):
    pizza = models.ForeignKey(Pizza, on_delete=models.CASCADE)

## Logic

cheese_pizza = Pizza.objects.create(name='Cheese')
mozzarella = Topping.objects.create(name='mozzarella')
mozzarella.pizzas.add(cheese_pizza)

mozzarella.pizzas.all() -> <QuerySet [<Pizza: Cheese>]>



如何在不影响Pizza表中原始披萨对象的情况下,将链接了浇头的披萨对象添加到Orders表中,以使Pizza.objects.get(name="2 Topping")始终返回未链接浇头对象的对象?

1 个答案:

答案 0 :(得分:0)

  

客户订购了“ 2浇头”和“意大利辣味香肠”和“蘑菇” ...

对此建模的正常方法是将浇头作为订单的一部分。 PizzaTopping就是事物的类型,而Order则记录了每个订单的特定选择。

class Pizza(models.Model):
    name = models.CharField(max_length=30)

class Topping(models.Model):
    name = models.CharField(max_length=30)

class Order(models.Model):
    pizza = models.ForeignKey(Pizza, on_delete=models.CASCADE, related_name='orders')
    toppings = models.ManyToManyField('Topping', related_name='orders')

如果某些披萨被烤制(可以这么说),那么您可以将浇头作为PizzaOrder的一部分,也许还有一些其他信息表明了多少个浇头允许进行验证。但是,由于这显然不是您的真实代码,因此很难说出对问题建模的最佳方法是什么。