DRF : Пользовательский дочерний сериализатор для добавления поля из родителя
В моей текущей модели есть JSON поле под названием "data", ранее поля "foo" и "bar" находились внутри JSON поля. По причинам производительности мне пришлось вынести foo и bar в специальные поля с помощью миграции django.
но я хотел бы сохранить тот же формат конечной точки при обращении к API. Это означает, что нужно поместить "foo" и "bar" в class DataSerializer(serializers.Serializer)
Как можно передать данные из FooModelSerializer() в DataSerializer() ?
формат вывода конечной точки:
"results": [
{
"id": 1
"data": {
"json_field_A": "charValue",
"json_field_B": 123,
"json_field_C": "charValue",
"foo": 12,
"bar": "barValue"
},
"other": 12345
},
{
"id": 2
"data": {
"json_field_A": "charValue",
"json_field_B": 123,
"json_field_C": "charValue",
"foo": 12,
"bar": "barValue"
},
"other": 12345
}
]
модель :
class FooModel(models.Model):
data = models.JSONField(
blank=False,
null=False,
default=some_default
)
foo = models.IntegerField()
bar = models.CharField()
other = models.IntegerField()
сериализатор :
class DataSerializer(serializers.Serializer):
json_field_A = fields.CharField()
json_field_B = fields.IntegerField()
json_field_C = fields.CharField()
class FooModelSerializer(serializers.ModelSerializer):
data = DataSerializer()
class Meta:
model = models.FooModel
fields = ['id', 'data', 'other', 'foo', 'bar']
Вы можете использовать ListAPIView, чтобы как бы объединить эти два сериализатора и написать одно представление, которое обрабатывает их оба.
class CombinedListView(ListAPIView):
serializer_class_data = DataSerializer
serializer_class_foo = FooModelSerializer
def get_data(self):
return DataModel.objects.all()
def get_foo(self):
return FooModel.objects.all()
def list(self, request, *args, **kwargs):
data = self.serializer_class_data(self.get_data(), many=True)
foo = self.serializer_class_foo(self.get_foo(), many=True)
return Response({"data": data, "foo": foo})
Я предлагаю вам использовать некоторые методы класса и вызывать их внутри основного метода, возвращающего ответ.
Вот ссылка на аналогичную ситуацию: Combining Views