chibisov / drf-extensions

DRF-extensions is a collection of custom extensions for Django REST Framework

Home Page:http://chibisov.github.io/drf-extensions/docs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

PartialUpdateSerializerMixin does not support nested fields of the same model

tuky opened this issue · comments

Assume a model Author with fields

first_name = modes.CharField(…)
last_name = modes.CharField(…)

then assume this "nested" model serializer combination

class NameSerializer(ModelSerializer):
    first = modes.CharField(source='first_name')
    last = modes.CharField(source='last_name')

    class Meta:
        model = Author
        fields = ['first_name', 'last_name']


class AuthorSerializer(PartialUpdateSerializerMixin, ModelSerializer):
    name = NameSerializer(source='*')
    class Meta:
        model = Author
        fields = ['name']

for this it becomes impossible to PATCH the name field, because get_fields_for_partial_update does not correctly determine the model fields. This should be possible, because without the PartialUpdateSerializerMixin the name can be PATCHed. The use case here is to group/structure/namespace the data in the serializer, not using any relations.

this is the recursive approach we're currently monkey patching to make things work:

orig_get_fields_for_partial_update = serializers.get_fields_for_partial_update


def get_fields_for_partial_update(opts, init_data, fields, init_files=None):
    update_fields = orig_get_fields_for_partial_update(opts, init_data, fields, init_files)

    for k, v in (init_data or {}).items():
        if isinstance(v, dict) and k in fields and fields[k].source == '*':
            recursive_fields = get_fields_for_partial_update(opts, v, fields[k].fields.fields)
            update_fields.extend(recursive_fields)

    return update_fields


serializers.get_fields_for_partial_update = get_fields_for_partial_update

would this work for you in a PR?

sure. but add unit and functional tests for that as well.