Integrity Error in Django Rest Framework while Saving In DB?

25 Views Asked by At

I want to write an api which insert into two of my table cart and cartitem. So I write two serializes for this purpose and a view. When i tried to pass all data from json it is working fine. But i want to try getting price from MenuItem Model and calculate the amount and then insert into my tables. Here I got the following error. django.db.utils.IntegrityError: NOT NULL constraint failed: orders_cartitem.pricedjango.db.utils.IntegrityError: NOT NULL constraint failed: orders_cartitem.price

class Cart(models.Model): 
    STATUS_CHOICES = [ ('pending', 'Pending'), ('completed', 'Completed'), ]

    cart_id = models.AutoField(primary_key=True)
    customer_id = models.ForeignKey(Accounts, on_delete=models.CASCADE, related_name='customer_carts')
    owner_id = models.ForeignKey(Accounts, on_delete=models.CASCADE, related_name='owner_carts')
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')

    def __str__(self):
        return f"Cart for customer: {self.customer_id}, owner: {self.owner_id}, order: {self.cart_id}"


class CartItem(models.Model):
    cart = models.ForeignKey(Cart, on_delete=models.CASCADE)
    item = models.ForeignKey(MenuItem, on_delete=models.CASCADE)
    quantity = models.IntegerField()
    price = models.FloatField()
    amount = models.FloatField()
    created_at = models.DateTimeField(auto_now_add=True)

    # updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return f"{self.item.name}-{self.cart}" 

# serializes.py
class CartItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = CartItem
        fields = ['item', 'quantity', 'price', 'amount', 'created_at']
        read_only_fields = ['price', 'created_at', 'amount']


class CartItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = CartItem
        fields = ['item', 'quantity', 'price', 'amount', 'created_at']
        read_only_fields = ['price', 'created_at', 'amount']


class CartSerializer(serializers.ModelSerializer):
    cart_items = CartItemSerializer(many=True, read_only=True)  # Serializer for the nested CartItems

    class Meta:
        model = Cart
        fields = ['cart_id', 'customer_id', 'owner_id', 'status', 'cart_items']

    def create(self, validated_data):
        # print(validated_data.pop('cart_items'))
        cart_items_data = validated_data.pop('cart_items', [])  # Extract cart items data if available
        print(f"cart_items_data {cart_items_data}")
        cart = Cart.objects.create(**validated_data)  # Create the Cart instance

        # Create related CartItems
        for cart_item_data in cart_items_data:
            CartItem.objects.create(cart=cart, **cart_item_data)

        return cart
# views.py
class CreateCartWithItemsAPIView(generics.CreateAPIView):
    serializer_class = CartSerializer
    permission_classes = [IsAuthenticated]

    def create(self, request, *args, **kwargs):
        vendor_id = request.data.get('vendor_id')
        existing_cart = Cart.objects.filter(owner_id=vendor_id).first()

        if existing_cart:
            cart_serializer = self.get_serializer(existing_cart, data=request.data)
        else:
            cart_serializer = self.get_serializer(data=request.data)

        if cart_serializer.is_valid():
            cart = cart_serializer.save()

            cart_items_data = request.data.get('cart_items', [])
            for item_data in cart_items_data:
                item_id = item_data.get('item')
                try:
                    item = MenuItem.objects.get(id=item_id)
                    item_data['price'] = item.price
                    amount = item.price * item_data['quantity']
                    item_data['amount'] = amount
                except MenuItem.DoesNotExist:
                    return Response({"error": f"Item with id {item_id} does not exist"},
                                    status=status.HTTP_404_NOT_FOUND)

            cart_item_serializer = CartItemSerializer(data=cart_items_data, many=True)
            if cart_item_serializer.is_valid():
                cart_item_serializer.save(cart=cart)
                return Response(cart_serializer.data, status=status.HTTP_201_CREATED)
            else:
                cart.delete()
                return Response(cart_item_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response(cart_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
I want my json like this:
{
    "customer_id": 8,
    "owner_id": 4,
    "status": "pending",
    "cart_items": [
        {
            "item": 2,
            "quantity": 2
        }
    ]
}

But i got error in price not null. I printed data in view, and it's working fine but it's not working in serializes i think.

0

There are 0 best solutions below