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

Вернуться на верх