[Django]-Multiple models save in a POST request. (Invalid data. Expected a dictionary, but got list.)

4๐Ÿ‘

โœ…

I have resolved the issues by updating the serializer as follows.

serializers.py

class CustomerPreferencesSerializer(serializers.ModelSerializer):
    model = CustomerPreferences
    user = serializers.CharField(read_only=True)
    class Meta:
        model = CustomerPreferences
        fields = '__all__'


class CustomerPreferencesListSerializer(serializers.ModelSerializer):
    model = Preferences
    customer_preferences = serializers.SerializerMethodField()

    def get_customer_preferences(self, obj):
        request = self.context.get('request')
        customer_id = request.query_params.get('customer_id', None)
        customer_pref = CustomerPreferences.objects.filter(preference_id=obj, customer=customer_id)
        serializer = CustomerPreferencesSerializer(customer_pref, many=True)
        return serializer.data



    class Meta:
        model = Preferences
        fields = ('id', 'title','status')


class CustomerPreferenceSaveSerializer(serializers.Serializer):
    model = Customer
    customer_preferences = CustomerPreferencesSerializer(source='customer_customer_preferences', many=True,read_only=True)

    class Meta:
        model = Customer
        fields = ('customer','customer_preferences',)

    def create(self, validated_data):
        request = self.context.get('request')
        customer = request.data.get('customer', None)
        customer_preferences_data = request.data.get('customer_preferences', [])

        # first delete all entries of the given customer
        customer_preferences_obj = CustomerPreferences.objects.filter(customer=customer)
        customer_preferences_obj.delete()

        for cust_prefernce in customer_preferences_data:
            cust_prefernce_obj = CustomerPreferences.objects.create(
                preference_id=cust_prefernce['preference'],
                status=cust_prefernce['status'],
                customer_id = customer,
                user = request.user
            )

        return Customer.objects.all().get(id=customer)

views.py

class PreferencesViewSet(viewsets.ModelViewSet):
serializer_class = PreferencesSerializer
queryset = Preferences.objects.all()


class CustomerPreferenceViewSet(viewsets.ModelViewSet):
    serializer_class = CustomerPreferencesSerializer
    queryset = CustomerPreferences.objects.all()

    model = CustomerPreferences

    def get_queryset(self):
        queryset = Preferences.objects.all()
        return queryset

    def get_serializer_class(self):
        if self.action == 'list' or self.action == 'retrieve':
            return CustomerPreferencesListSerializer
        return CustomerPreferenceSaveSerializer
๐Ÿ‘คArun SS

0๐Ÿ‘

You have posted the model CustomerPreferences which defines a mapping between a customer and a preference.

The serializer you posted is the one for this mapping โ€“ it serializes the relation between one preference and one customer.

I think you want to display/update the preferences of one customer so my answer is based on that assumption.

With your current model structure you get the CustomerPreferences of one customer with customer.customer_customer_preferences.all(). You need a CustomerSerializer that uses the CustomerPreferencesSerializer(many=True) to handle multiple preferences:

class CustomerSerializer(Serializer):
     model = Customer
     # ... more fields
     customer_preferences = CustomerPreferencesSerializer(source='customer_customer_preferences', many=True)

Code is not tested. You will probably need custom code for saving.

See http://www.django-rest-framework.org/api-guide/relations/#nested-relationships

๐Ÿ‘คRisadinha

Leave a comment