Сквозная модель идеально подходит для этого. ManyToManyFields
создает этот вид базы данных в фоновом режиме, который создает только уникальные комбинации Pizza и PizzaOrder, но вы можете легко реализовать это самостоятельно.
Просто создайте класс с именем PizzaOrderItem
, который содержит ForeignKeys
для моделей Pizza и PizzaOrder:
class PizzaOrderItem(models.Model):
pizza = ForeignKey(Pizza)
pizza_order = ForeignKey(PizzaOrder)
Затем вы можете изменить ManyToManyField, чтобы использовать свой пользовательский, созданный с помощью модели:
class PizzaOrder(models.Model):
...
items = models.ManyToManyField(Pizza, through='<your_app_name>.PizzaOrderItem',
blank=False,
null=False)
...
Вы можете даже добавить дополнительные поля в своймодель, как начинки или количество, например:
class PizzaOrderItem(models.Model):
pizza = ForeignKey(Pizza)
pizza_order = ForeignKey(PizzaOrder)
toppings = ManyToManyField(Toppings)
quantity = IntegerField(default=1)
Пиццу можно получить в заказе через order.items
, а фактические через объекты модели - через order.pizza_order_item_set
.
Сериализаторы
Получить товары для заказа довольно просто. Чтобы правильно отобразить ваш новый PizzaOrderItems
, вам нужно добавить сериализатор и установить элементы на PizzaOrderSerializer
для использования вашего нового сериализатора:
class PizzaOrderItemSerializer(serializer.ModelSerializer):
class Meta:
model = PizzaOrderItem
# If you add a field like quantity you can add them to the fields list below.
fields = ['pizza', 'pizza_order']
class PizzaOrderSerializer(serializer.ModelSerializer):
items = PizzaOrderItemSerializer(source='pizza_order_item_set', many=True)
class Meta:
model = PizzaOrder
fields = ['id', 'items', 'status', 'created']
Создание PizzaOrderItems
Существует два способа создания PizzaOrderItems. Первый довольно прост. Просто создайте представление, похожее на PizzaOrder
, и используйте PizzaOrderItemSerializer
:
class PizzaOrderItemViewSet(generics.ListCreateAPIView):
queryset = PizzaOrderItem.objects.all()
serializer_class = PizzaOrderItemSerializer
Затем вы можете создавать позиции для заказа, используя данные POST:
{
"pizza" : <pizza_id_here>
"pizza_order" : <pizza_order_id_here>
}
Второй способ - использовать только представление PizzaOrder и переопределить функции создания для сериализатора PizzaOrder. Это связано с тем, что по умолчанию вложенный сериализатор доступен только для чтения, поэтому мы переопределяем метод create для корневого сериализатора и создаем подобъекты, используя проверенные данные вложенного сериализатора.
class PizzaOrderSerializer(serializer.ModelSerializer):
...
def create(self, validated_data):
items = validated_data.pop('items')
order = PizzaOrder.objects.create(**validated_data)
for item_data in items:
PizzaOrderItem.objects.create(pizza_order=order, **item_data)
return order
ЕслиВы используете этот метод, вы можете создать заказ с данными POST это:
{
"items": [
{ "pizza" : 1 },
{ "pizza" : 1 },
{ "pizza" : 2 },
{ "pizza" : 2 },
]
"status": 1
}