Search code examples
djangodjango-modelsdjango-rest-frameworkdjango-viewsdjango-serializer

'Meal' object is not iterable django rest framework


I'm making an api with the ability to add a product to the cart, when I receive an empty basket, everything works, but as soon as the product gets into the basket, it gives me an error 'Meal' object is not iterable

It's models.py

class Meal(models.Model):
    """Meal"""

    title = models.CharField(max_length=255)
    description = models.TextField(default='The description will be later')
    price = models.DecimalField(max_digits=9, decimal_places=2)
    restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE, null=True)
    slug = models.SlugField()

class CartMeal(models.Model):
    """Cart Meal"""

    user = models.ForeignKey('Customer', on_delete=models.CASCADE)
    cart = models.ForeignKey('Cart', verbose_name='Cart', on_delete=models.CASCADE, related_name='related_meals')
    meal = models.ForeignKey(Meal, verbose_name='Meal', on_delete=models.CASCADE)
    qty = models.IntegerField(default=1)
    final_price = models.DecimalField(max_digits=9, decimal_places=2)

class Cart(models.Model):
    """Cart"""

    owner = models.ForeignKey('Customer', on_delete=models.CASCADE)
    meals = models.ManyToManyField(CartMeal, related_name='related_cart', blank=True)
    total_products = models.PositiveIntegerField(default=0)
    final_price = models.DecimalField(max_digits=9, decimal_places=2, default=0)
    in_orders = models.BooleanField(default=False)
    for_anonymous_user = models.BooleanField(default=False)

It's serializers.py

class CartMealSerializer(serializers.ModelSerializer):

    meal = MealSerializer(many=True)

    class Meta:
        model = CartMeal
        fields = ['id', 'meal', 'qty', 'final_price']

class CustomerSerializer(serializers.ModelSerializer):

    user = serializers.SerializerMethodField()

    class Meta:
        model = Customer
        fields = '__all__'


class CartSerializer(serializers.ModelSerializer):

    meals = CartMealSerializer(many=True)
    owner = CustomerSerializer()

    class Meta:
        model = Cart
        fields = '__all__'

It's views.py Here I call the get method, after which I get an error

class CartViewSet(viewsets.ModelViewSet):

    serializer_class = CartSerializer
    queryset = Cart.objects.all()

    @staticmethod
    def get_cart(user):
        if user.is_authenticated:
            return Cart.objects.get(owner=user.customer, for_anonymous_user=False)
        return Cart.objects.get(for_anonymous_user=True)

    @staticmethod
    def _get_or_create_cart_meal(customer: Customer, cart: Cart, meal: Meal):
        cart_meal, created = CartMeal.objects.get_or_create(
            user=customer,
            meal=meal,
            cart=cart,
        )
        return cart_meal, created

    @action(methods=['GET'], detail=False)
    def current_customer_cart(self, *args, **kwargs):
        cart = self.get_cart(self.request.user)
        cart_serializer = CartSerializer(cart)
        return response.Response(cart_serializer.data)

Please show me where the error is


Solution

  • The meal of a CartMeal model is a ForeignKey, that means that it refers to (at most) one Meal object, therefore you can not use many=True in the serializer:

    class CartMealSerializer(serializers.ModelSerializer):
        meal = MealSerializer()  # ← no many=True
    
        class Meta:
            model = CartMeal
            fields = ['id', 'meal', 'qty', 'final_price']