Search code examples
djangodjango-rest-frameworkdjango-serializer

Problem with POST from fronside. Method does not support writable dotted-source fields by default


I create some dotted source field in my serializer. I did it cause have to display name value of foreign key not pk value. But when I trying to POST from frontend djang throws this : AssertionError at /api/my-api/ The .create() method does not support writable dotted-source fields by default. Write an explicit .create() method for serializer MySerializer, or set read_only=True on dotted-source serializer fields.

So, when I set read_only = True my POST from frontend to request null for every field from dotted-source serializer fields.

This is my serializer:

class FcaWorksSerializer(serializers.ModelSerializer):
    fell_form = serializers.CharField(source="fell_form.name" )
    #...
    main_type = serializers.CharField(source="main_type.name")

    class Meta:
        model = FcaWorks
        fields = ('id_fca','wkod', 'main_type','fell_form','fell_type','kind',\
        'sortiment','vol_drew','use_type','fca_res','ed_izm','vol_les','act_name',\
        'obj_type','use_area','indicator','comment','date_report')

How I can to solve this problem?


Solution

  • Override the __init__() method of the serializer to adjust the serializer condition

    class FcaWorksSerializer(serializers.ModelSerializer):
        fell_form = serializers.CharField()
        # ...
        main_type = serializers.CharField()
    
        class Meta:
            model = FcaWorks
            fields = ('id_fca', 'wkod', 'main_type', 'fell_form', 'fell_type', 'kind',
                      'sortiment', 'vol_drew', 'use_type', 'fca_res', 'ed_izm', 'vol_les', 'act_name',
                      'obj_type', 'use_area', 'indicator', 'comment', 'date_report')
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            if self.context['request'].method == 'GET':
                self.fields['fell_form'].source = "fell_form.name"
                self.fields['main_type'].source = "main_type.name"
    
        def create(self, validated_data):
            # here you will get the data
            fell_form = validated_data['fell_form']
            main_type = validated_data['main_type']