Как создавать заказы и заказывать предметы в DRF

Я хочу знать, как эффективно я могу создать заказ и его элементы в DRF, используя представления и сериализаторы. Я отправляю many=True для POST-запроса OrderItemSerializer, потому что у меня будет список элементов заказа и я хочу, чтобы они были подтверждены сразу.

Мои вопросы:

  1. Как передать и обновить поле order, полученное при создании order, в каждом OrderItem объекте .
  2. Я хочу, чтобы список элементов заказа создавался сразу, а не перебирал их все и выполнял OrderItems.objects.create(**validated_data)

views.py

class OrderAPIView(generics.GenericAPIView):
    permission_classes = [IsAuthenticated]
    serializer_class = OrderSerializer

    def get_object(self):
        return self.request.user
    
    def get_queryset(self):
        ...

    def get(self, request):
        ...

    def post(self, request):
        serializer = self.serializer_class(data = request.data)
        if serializer.is_valid():
            serializer.validated_data['user'] = self.get_object()
            order = serializer.save()

            # create order items

            return Response(serializer.data, status = status.HTTP_201_CREATED)
        return Response(serializer.errors, status = status.HTTP_400_BAD_REQUEST)

serializers.py

class OrderSerializer(serializers.ModelSerializer):
    PENDING, CONFIRMED, SHIPPED = "PENDING", "CONFIRMED", "SHIPPED"
    OUT_FOR_DELIVERY, DELIVERED, CANCELLED =  "OUT_FOR_DELIVERY", "DELIVERED", "CANCELLED"

    ORDER_STATUS_CHOICES = [
        (PENDING, "Order Pending"),
        (CONFIRMED, "Order Confirmed"),
        (SHIPPED, "Shipped"),
        (OUT_FOR_DELIVERY, "Out for Delivery"),
        (DELIVERED, "Delivered"),
        (CANCELLED, "Cancelled")
    ]

    total_price = serializers.DecimalField(max_digits = 7, decimal_places = 2)
    user = serializers.SlugRelatedField(slug_field = 'email', read_only = True)
    user_address = UserAddressSerializer()
    is_paid = serializers.BooleanField(default = False)
    status = serializers.ChoiceField(choices = ORDER_STATUS_CHOICES, default = PENDING)
    razorpay_order_id = serializers.CharField(min_length = 5, max_length = 50, read_only = True)
    created_at = serializers.DateTimeField(read_only = True)
    updated_at = serializers.DateTimeField(read_only = True)

    class Meta:
        model = Order
        fields = [
            'id', 'total_price', 'user', 'user_address', 'is_paid', 'status', 'razorpay_order_id', 
            'created_at', 'updated_at'
        ]

    def validate(self, attrs):
        return super().validate(attrs)

    def create(self, validated_data):
        # Create order in RazorPay
        total_price = self.validated_data['total_price']
        
        razorpay_order = RAZORPAY_CLIENT.order.create({
            "amount": int(total_price) * 100, 
            "currency": "INR", 
            "payment_capture": "1"
        })

        validated_data['razorpay_order_id'] = razorpay_order['id']
        return super().create(**validated_data)
    
class OrderItemSerializer(serializers.ModelSerializer):
    order = serializers.SlugRelatedField(slug_field = 'id', queryset = Order.objects.select_related('user', 'user_address').all())
    product = serializers.SlugRelatedField(slug_field = 'id', queryset = Product.objects.all())
    quantity = serializers.IntegerField(min_value = 1, max_value = 10)
    created_at = serializers.DateTimeField(read_only = True)
    updated_at = serializers.DateTimeField(read_only = True)

    class Meta:
        model = OrderItem
        fields = ['id', 'order', 'product', 'quantity', 'created_at', 'updated_at']

    def validate(self, attrs):
        return super().validate(attrs)

    def create(self, validated_data):
        return super().create(validated_data)

Мое тело запроса может быть примерно таким

{
    "total_price": 1234,
    "user_address": {
        # Nested fields
    },
    "order_items": [
        {
            "product_id": 1,
            "quantity": 2
        },
        {
            "product_id": 2,
            "quantity": 4
        }
    ]
}
Вернуться на верх