Динамическое c поле вложенного сериализатора Django REST Framework - PullRequest
1 голос
/ 19 февраля 2020

Я пытаюсь использовать сериализатор родительской модели с вложенным сериализатором в качестве поля, который отличается от другого строкового поля.

Например, если поле registry_type равно intra Я хочу использовать _IntraRegistrySerializer для сериализации / десериализации поля registry_data, но если registry_type равно slack, я хочу использовать _SlackRegistrySerializer для того же поля.

Мне удалось чтобы сериализация работала так:

class RegistrySerializer(serializers.ModelSerializer):

    def to_representation(self, instance):
        data = super().to_representation(instance)
        if isinstance(instance, IntraRegistry):
            data["registry_type"] = "intra"
            data["registry_data"] = _IntraRegistrySerializer(instance=instance).data
        if isinstance(instance, SlackRegistry):
            data["registry_type"] = "slack"
            data["registry_data"] = _SlackRegistrySerializer(instance=instance).data
        return data

    class Meta:
        # `Registry` being the parent model of both `IntraRegistry` and `SlackRegistry`
        model = Registry
        fields = ["id", "description"]

Но это только половина того, что я хотел бы сделать.

Я пытался перегрузить методы, используя SerializerMethodField, и хотя я продолжайте искать и читать do c Я не могу найти решение.

1 Ответ

1 голос
/ 20 февраля 2020

Это похоже на хороший SerializerMethodField случай:

class RegistrySerializer(serializers.ModelSerializer):
    registry_type = serializers.SerializerMethodField()
    registry_data = serializers.SerializerMethodField()

    def get_registry_type(self, obj):
        if isinstance(instance, IntraRegistry):
            return "intra"
        if isinstance(instance, SlackRegistry):
            return "slack"

    def get_registry_data(self, obj):
        if isinstance(instance, IntraRegistry):
            return _IntraRegistrySerializer(instance=obj, context=self.context).data
        if isinstance(instance, SlackRegistry):
            return _SlackRegistrySerializer(instance=obj, context=self.context).data

    class Meta:
        # `Registry` being the parent model of both `IntraRegistry` and `SlackRegistry`
        model = Registry
        fields = ["id", "description", "registry_type", "registry_data"]

Выше приведена реализация полей метода сериализатора, и она должна работать, поскольку оба реестра наследуются от Registry.

Возможно, вам все еще придется настроить его под свои нужды. Одно отличие по сравнению с текущей реализацией состоит в том, что registry_type и registry_data теперь будут присутствовать всегда. Они будут null, если это тип объекта Registry или какой-либо другой дочерний тип, который здесь не обрабатывается.

...