如何使用 DRF 序列化器来使用多个序列化器并展平发送的数据

How to use DRF serializers to use multiple serializers and also flatten the data sent

我正在努力找出编写这些序列化程序的最佳方法。

我有这样的模型

class Foo(models.Model):
    db = models.CharField(max_length=30)
    name = models.CharField(max_length=30)
    schema = models.CharField(max_length=50)
    table_name = models.CharField(max_length=50)
    ext_type = models.CharField(max_length=100)
    sample_by = models.CharField()
    sample_by_val = models.CharField()

接下来我的序列化程序是这样的

 class SaveSerializer(serializers.ModelSerializer): #
     """
        Cannot figure out the best way to do this.
        This is just an example serializer I had in mind.
        I want to understand a cleaner/best way to do this.
     """
   sample = SampleSerializer()
   exts = ExtSerializer()

   class Meta:
     model = Foo

问题出在这里 - 以这种格式发送到此视图的数据

{
   "sample": {"sample_by":"weight", "sample_by_val":[30,50,60],"name":"test"}
   "exts": {"ext_type": "BY WEIGHT", "table":"EMPLOYEE"},
   "db" : "foobar",
   "schema" : "abcd"
}

class ExtSerializer(serializers.Serializer):
  table = serializers.CharField()
  ext_type = serializers.CharField()

class SampleSerializer(serializers.Serializer):
  sample_by = serializers.CharField()
  # Similar ones for sample_by_val and name

我正在努力写作SaveSerializer。它需要首先检查以特定格式发送的数据并将其传递给一些序列化程序。然后它需要展平该数据格式以将其存储在模型本身中。 有人可以帮助我了解执行此操作的最佳方法吗?这将非常有帮助!谢谢

您可以覆盖 to_representation() 和 to_internal_value(),我认为这是最好的方法。 Here is an example

抱歉,我会食言,只需像这样重写创建方法:

#override create method of serializer, you can easily handle object creation.
def create(self, validated_data):
    #first, pop sample and exts from validated data.
    sample = validated_data.pop('sample')
    exts = validated_data.pop('exts')

    #then, create object
    foo = Foo.objects.create(**validated_data, **sample, **exts)  #flat validated_data, sample, and exts to create Foo.
    return foo

#maybe you also want to handle representation, since the model of Foo doesn't has ext and sample fields
def to_representation(self, instance):
    sample = SampleSerializer(instance).data #SampleSerializer will deserialize sample_by field of Foo instance.
    exts = ExtSerializer(instance).data
    instance.sample = sample
    instance.exts = exts
    return super(SaveSerializer, self).to_representation(instance)