Django.fun

ImportError: cannot import name 'MealSerializer' from partially initialized module 'delivery_api.main.serializers'

When I insert this line cart = CartSerializer() into my serializer to get detailed information, I get an error ImportError: cannot import name 'MealSerializer' from partially initialized module 'delivery_api.main.serializers' (most likely due to a circular import). What is the reason for this and how to solve it?

cart/serializers.py

class CartMealSerializer(serializers.ModelSerializer):

    meal = MealSerializer()

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

class CartSerializer(serializers.ModelSerializer):

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

    class Meta:
        model = Cart
        fields = '__all__'

main/serializers.py

class OrderSerializer(serializers.ModelSerializer):

    cart = CartSerializer() *<--- This line causes an error*

    class Meta:
        model = Order
        fields = ['first_name', 'last_name', 'cart', 'phone', 'address', 'status', 'created_at']

Please help me solve this problem

Answers: 1

Answered by Willem Van Onsem, Sept. 14, 2021, 9:49 a.m.

You here have (likely) two files that try to import each other. This does not make sense since your main.serializers module aims to import the CartSerializer located in the cart.serializers module, and the cart.serializer module aims to import the MealSerializer defined in the main.serializers.

It also makes no sense that two serializers import each other: this would usually result in infinite recursion where the serializer of a Meal serializes its Order and that will serialize the related Meals. If you would serialize it like that, that would mean you have infinite recursion, and thus would generate a file with infinite cascades, so something like { 'cart': { 'meals': { 'meal': { 'cart': { 'meals': { 'meal': { … } } } } } } }.

You thus should define serializers that do not use another serializer, and use this to define a limited number of iterations. For example by defining a SimpleMealSerializer at the top of the cart.serializers module that does not make extra subserializations, so something like:

# cart/serializers.py

# no import of the MealSerializer

class SimpleMealSerializer(serializers.ModelSerializer):

    class Meta:
        model = Meal
        fields = ['title', 'description', 'price']

class CartMealSerializer(serializers.ModelSerializer):
    meal = SimpleMealSerializer()

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

class CartSerializer(serializers.ModelSerializer):
    meals = CartMealSerializer(many=True)
    owner = CustomerSerializer()

    class Meta:
        model = Cart
        fields = '__all__'