Можно ли переопределить SerializerMethodField для унаследованного Serializer?
Можно ли переопределить SerializerMethodField из унаследованного Serializer?
E.g.
# serializers.py
class BaseSerializer(serializers.ModelSerializer):
custom = serializers.SerializerMethodField()
class Meta:
model = Item
fields = ["pk", "custom"]
def get_custom(self, obj):
return "Base";
class ExtendedSerializer(BaseSerializer):
custom = serializers.SerializerMethodField()
class Meta:
model = Item
fields = ["pk", "custom"]
def get_custom(self, obj):
return "Extended";
Очевидно, что приведенный выше код не работает.
В настоящее время мне пришлось создать еще один Serializer и объявить новое SerializerMethodField для наследующих Serializers:
# serializers.py
class DefaultSerializer(serializers.ModelSerializer):
class Meta:
model = Item
fields = ["pk"]
class BaseSerializer(DefaultSerializer):
custom = serializers.SerializerMethodField()
class Meta:
model = Item
fields = ["pk", "custom"]
def get_custom(self, obj):
return "Base";
class ExtendedSerializer(DefaultSerializer):
custom = serializers.SerializerMethodField()
class Meta:
model = Item
fields = ["pk", "custom"]
def get_custom(self, obj):
return "Extended";
Но для моего случая использования было бы лучше, если бы я мог просто переопределить существующее поле SerializerMethodField, как в моем первом блоке кода.
На самом деле предложенное вами решение работает, и может быть еще более минимизировано до:
from rest_framework import serializers
class DefaultSerializer(serializers.ModelSerializer):
class Meta:
model = Item
fields = ['pk']
class BaseSerializer(DefaultSerializer):
custom = serializers.SerializerMethodField()
class Meta:
model = Item
fields = ['pk', 'custom']
def get_custom(self, obj):
return 'Base'
class ExtendedSerializer(BaseSerializer):
def get_custom(self, obj):
return 'Extended'
Таким образом, вам нужно упоминать поле custom
как SerializerMethodField
только один раз в BaseSerializer
. Просто переопределив реализацию get_custom
, можно получить данные, в которых ключ custom
будет 'Base'
при сериализации BaseSerializer
и 'Extended'
при сериализации ExtendedSerializer
.
Действительно, если мы сериализуем экземпляры, мы получим:
>>> BaseSerializer(Item.objects.first()).data
{'pk': 1, 'custom': 'Base'}
>>> ExtendedSerializer(Item.objects.first()).data
{'pk': 1, 'custom': 'Extended'}