Как сделать много ко многим ссылкам без изменения объекта записи

Я чувствую, что мне не хватает чего-то основного здесь, но я не могу понять это. Я приведу упрощенный пример того, чего я пытаюсь достичь. Возьмем, к примеру, этот типичный ресторан.

Если у меня есть таблица пиццы, которая заполнена записями названий пиццы. Еще одна таблица — записи пиццы-начинки. У них отношение многие ко многим. Если клиент заказывает «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.objects.get(name="2 Topping") всегда возвращал объект без связанных объектов начинки?


person COB    schedule 31.08.2019    source источник


Ответы (1)


Клиент заказывает "2 топпинга" с "Пепперони" и "Грибами"...

Обычный способ смоделировать это - включить начинку в заказ. Pizza и Topping обозначают типы вещей, а 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')

Если дело в том, что в некоторых пиццах запекаются начинки (так сказать), у вас могут быть начинки как часть как Pizza, так и Order, возможно, с некоторой дополнительной информацией, указывающей, сколько начинок разрешено для проверки. Однако, поскольку это явно не ваш реальный код, трудно сказать, как лучше всего смоделировать проблему.

person Kevin Christopher Henry    schedule 01.09.2019
comment
Это вывод, аналогичный тому, к которому я пришел. Хорошо получить подтверждение этому. Действительно, реальная проблема сложнее, однако это основная концепция, которую я пытался понять. Огромное спасибо за помощь. - person COB; 01.09.2019