Django Rest Framework - общий вложенный сериализатор для нескольких моделей с одним базовым классом
Предположим, что у нас есть следующие модели:
from django.db import models
class BaseModel(models.Model):
field_a = models.TextField()
field_b = models.IntegerField()
class Meta:
abstract = True
class ModelA(BaseModel):
some_relation = models.ForeignKey(
"app.RelatedModelA",
related_name="model_a_set",
...
)
class ModelB(BaseModel):
different_relation = models.ForeignKey(
"app.RelatedModelB",
related_name="model_b_set",
...
)
class RelatedModelA(models.Model):
pass
class RelatedModelB(models.Model):
pass
Я хотел бы иметь возможность определять сериализаторы следующим образом:
from rest_framework import serializers
class RelatedModelASerializer(serializers.ModelSerializer):
model_a_set = BaseModelSerializer(many=True)
class Meta:
model = RelatedModelA
fields = ("id", "model_a_set")
class RelatedModelBSerializer(serializers.ModelSerializer):
model_b_set = BaseModelSerializer(many=True)
class Meta:
model = RelatedModelB
fields = ("id", "model_b_set")
Вопрос в том, как определить BaseModelSerializer? Я нашел решение, которое учитывает переопределение to_representation, хотя это требует написания сериализаторов для каждого типа отдельно (ModelASerializer и ModelBSerializer), так что это будет выглядеть следующим образом:
class BaseModelSerializer(serializers.ModelSerializer):
def to_representation(self, obj):
if isinstance(obj, ModelA):
return ModelASerializer(obj, context=self.context).to_representation(obj)
elif isinstance(obj, ModelB):
return ModelBSerializer(obj, context=self.context).to_representation(obj)
raise NotImplementedError
class Meta:
model = BaseModel
fields = ("id", "field_a", "field_b")
Идеальным решением для меня было бы нечто подобное, без определения сериализаторов для ModelA и ModelB:
class BaseModelSerializer(serializers.ModelSerializer):
class Meta:
model = BaseModel
fields = ("id", "field_a", "field_b")
но, к сожалению, так не получится, потому что абстрактная модель не может быть задана в Meta. Можно ли это как-то решить понятным способом, не определяя ModelASerializer и ModelBSerializer явно?