Я хочу реализовать функцию добавления заказа в ресторане. У заказа есть два поля mtm, объекты которых создаются в момент создания заказа. Каким образом мне это сделать? Желательно одним запросом, в рамках одной транзакции.
Вот объект заказа:
# заказ
class Order(models.Model):
user = models.ForeignKey(UserProfile, verbose_name='Пользователь', on_delete=models.CASCADE, null=False)
positions = models.ManyToManyField(OrderPosition, verbose_name='Позиции', related_name='order')
address = models.CharField(verbose_name='Адресс доставки', blank=True, max_length=200)
created = models.DateTimeField(verbose_name='Время создания заказа', default=timezone.now, null=False, blank=True)
with_self = models.BooleanField(verbose_name='С собой', default=False)
delivery_method = models.ForeignKey(DeliveryMethod, verbose_name='Способ доставки', on_delete=models.SET_NULL,
null=True, blank=True)
payment_method = models.ForeignKey(PaymentMethod, verbose_name='Способ оплаты', on_delete=models.SET_NULL,
null=True, blank=True)
processed = models.BooleanField(verbose_name='Заказ принят в обработку', default=True, blank=True)
cook = models.BooleanField(verbose_name='Блюда готовятся', default=False, blank=True)
deliver = models.BooleanField(verbose_name='Доставляется', default=False, blank=True)
completed = models.BooleanField(verbose_name='Завершен', default=False, blank=True)
Вот объект позиции в заказе:
# позиция в заказе
class OrderPosition(models.Model):
position = models.ForeignKey(Position, on_delete=models.CASCADE)
count = models.IntegerField(verbose_name='Количество в заказе', default=1)
dishes = models.ManyToManyField(Dish, verbose_name='Выбранные блюда', related_name='dishes')
toppings = models.ManyToManyField(Topping, verbose_name='Выбранные допинги', related_name='toppings', blank=True)
Вот их сериализаторы:
# позиция в заказе
class OrderPositionRequestSerializer(serializers.ModelSerializer):
class Meta:
model = OrderPosition
fields = '__all__'
# заказ
class OrderRequestSerializer(serializers.ModelSerializer):
position_set = OrderPositionRequestSerializer(many=True, read_only=True, source='positions')
class Meta:
model = Order
fields = (
'user',
'address',
'created',
'with_self',
'delivery_method',
'payment_method',
'processed',
'cook',
'deliver',
'completed',
'position_set'
)
Слово "Request" в названии сериализатора означает, что им я сериализую тот json, который мне приходит от пользователя. Есть так же ResponseSerializers, которыми я сериализую собственные QuerySets перед отправкой пользователю. Выглядят они так:
class OrderPositionResponseSerializer(serializers.ModelSerializer):
pos = PositionResponseSerializer(many=False, read_only=True, source='position')
dish_set = DishResponseSerializer(many=True, read_only=True, source='dishes')
topping_set = ToppingResponseSerializer(many=True, read_only=True, source='toppings')
class Meta:
model = OrderPosition
fields = (
'pos',
'count',
'dish_set',
'topping_set'
)
# заказ
class OrderResponseSerializer(serializers.ModelSerializer):
owner = UserProfileResponseSerializer(many=False, read_only=True, source='user')
delivery = DeliveryMethodResponseSerializer(many=False, read_only=True, source='delivery_method')
payment = PaymentMethodResponseSerializer(many=False, read_only=True, source='payment_method')
position_set = OrderPositionResponseSerializer(many=True, read_only=True, source='positions')
class Meta:
model = Order
fields = (
'id',
'owner',
'position_set',
'address',
'created',
'with_self',
'delivery',
'payment',
'processed',
'cook',
'deliver',
'completed'
)
Помогите так же добрым советом, насколько хороша такая техника обработки запросов и ответов? Я до этого сам додумался, а значит в этом есть подвох (ЭТО ЗАКОН!)
Так выглядит моя вьюха:
# заказы
class OrderView(APIView):
def get(self, request):
owner_id = request.data.get('owner_id')
if owner_id:
user = get_object_or_404(UserProfile.objects.all(), id=owner_id)
if user.is_staff:
orders = Order.objects.all()
else:
orders = Order.objects.filter(user__id=owner_id)
else:
return Response({'error': 'Укажите owner_id.'})
serializer = OrderResponseSerializer(orders, many=True)
return Response({'orders': serializer.data})
def post(self, request):
order = request.data.get('order')
order_serializer = OrderRequestSerializer(data=order)
if order_serializer.is_valid(raise_exception=True):
order_saved = order_serializer.save()
return Response({
'success': 'Заказ %s был успешно добавлен.' % order_saved.id,
'order': order_serializer.data
})
Я не так давно изучаю drf и не далеко зашел в плане доков, так что буду рад даже просто ссылке на пример или на официальную документацию, просто я видимо пропустил тот момент, где в обработке запроса задействуются сразу несколько таблиц бд. Спасибо!