Django REST Framework: Есть ли у ModelSerializer возможность динамического изменения полей с помощью GET или (POST, PUT, DELETE)?

Есть ли у ModelSerializer возможность динамического изменения полей с помощью GET или (POST, PUT, DELETE)?

В то время как для GET требуются сложные поля, такие как вложенные сериализаторы, они не требуются для (POST, PUT, DELETE).

Я думаю, что решение состоит в том, чтобы использовать отдельные сериализаторы для GET и (POST, PUT, DELETE). Но в этом случае мне придется создать довольно много бесполезных сериализаторов. Есть ли какое-нибудь хорошее решение?

сначала нужно создать класс и унаследовать от него свой сериализатор, как показано ниже:

from rest_framework import serializers


class DynamicFieldsModelSerializer(serializers.ModelSerializer):
    """To be used alongside DRF's serializers.ModelSerializer"""
    @classmethod
    def default_fieldset(cls):
       return cls.Meta.fields

    def __init__(self, *args, **kwargs):
        self.requested_fields = self._extract_fieldset(**kwargs)
        # Fields should be popped otherwise next line complains about 
unexpected kwarg
        kwargs.pop('fields', None)
        super().__init__(*args, **kwargs)
        self._limit_fields(self.requested_fields)

    def _extract_fieldset(self, **kwargs):
        requested_fields = kwargs.pop('fields', None)
        if requested_fields is not None:
            return requested_fields

        context = kwargs.pop('context', None)
        if context is None:
            return None

        return context.get('fields')

    def _limit_fields(self, allowed_fields=None):
        if allowed_fields is None:
            to_exclude = set(self.fields.keys()) - set(self.default_fieldset())
        else:
            to_exclude = set(self.fields.keys()) - set(allowed_fields)
        for field_name in to_exclude or []:
            self.fields.pop(field_name)

    @classmethod
    def all_fields_minus(cls, *removed_fields):
        return set(cls.Meta.fields) - set(removed_fields)

тогда ваш сериализатор будет выглядеть примерно так:

class PlaylistSerializer(DynamicFieldsModelSerializer):
    class Meta:
        model = Playlist
        fields = ("pk", "user", "title", "views", "is_public",
        "is_wl", "created_at", "updated_at", "tracks", "is_owner",
        "is_added", "is_favorited",)

    @classmethod
    def update_serializer(cls):
        return ("title", "is_public")
    
    @classmethod
    def view_serializer(cls):
        return ("title", "is_public", "is_owner", "is_added")

тогда вы вызовете ваш сериализатор следующим образом:

PlaylistSerializer(instance, fields=PlaylistSerializer.update_serializer()).data
Вернуться на верх