【问题标题】:Access create method of nested serializer访问嵌套序列化程序的创建方法
【发布时间】:2019-06-15 02:12:42
【问题描述】:

我有一个包含两个子序列化程序的父序列化程序。子序列化器被重复使用,它们具有更新和创建的逻辑。

我的请求数据是这样的,

{
 'key1': [
          {'keyA': value},
          {'keyA': value}
        ]
 'key2': [
          {'keyB': value},
          {'keyB': value}
         ]
}

这些是我写的序列化器,

class ParentSerializer(serializers.Serializer):
    key1 = Key1Serializer(many=True)
    key2 = Key2Serializer(many=True)

    class Meta:
    ...

子序列化器,

class Key1Serializer(serializers.ModelSerializer):
    keyA = serializers.CharField(required=True)
    class Meta:
       model = Key1
       fields = ('keyA')
    list_serializer_class = MultipleKey1Serializer
class Key1Serializer(serializers.ModelSerializer):
    keyB = serializers.CharField(required=True)
    class Meta:
       model = Key2
       fields = ('keyB')
    list_serializer_class = MultipleKey2Serializer

列出序列化程序,

class MultipleKey1Serializer(serializers.ListSerializer):
    def update(self, extra_params):
        for el in self.validated_data:
           ... #update logic
class MultipleKey2Serializer(serializers.ListSerializer):
    def create(self, extra_params):
        for el in self.validated_data:
           ... #create logic

这就是我初始化父序列化程序的方式

serializer = ParentSerializer(data=request_data)
serializer.is_valid() # <- works perfectly, validates all the fields

因此嵌套的序列化程序可以完美地验证数据。现在我要做的就是在Key1Serializer 中调用update 方法并在Key2Serializer 中调用create 方法。

我试着用懒惰的方式来称呼它,

serializer.data['key2'].create(params)

但这不是正确的做法。谁能帮帮我?

【问题讨论】:

  • 那么当您尝试以这种方式调用它时是否遇到任何错误?错误是什么?
  • serializer.data['key2'] 返回验证数据列表。所以在列表中调用.create(params) 会给出错误list object does not have 'create'...

标签: python django python-3.x django-rest-framework django-serializer


【解决方案1】:

正如您已经发现的那样,嵌套的序列化程序实例在验证后不会保存在任何地方,因此您必须再次手动创建它们。您可以在父序列化程序的 create 方法中执行此操作:

def create(self, validated_data):
    k1_data = validated_data.pop('key1')
    k2_data = validated_data.pop('key2')

    instance = super().create(validated_data)

    serializer = Key1Serializer(k1_data, context=self.context, many=True)
    serializer.is_valid(raise_exception=True)
    serializer.save()

    serializer2 = Key2Serializer(k2_data, context=self.context, many=True)
    serializer2.is_valid(raise_exception=True)
    serializer2.save()

    return instance

【讨论】:

  • 有什么方法可以保存第一次创建的实例?
  • @dhiraj 我认为在更新的情况下这样做没有多大意义,因为它们是在没有模型实例的情况下初始化的,纯粹是为了验证嵌套数据。它们在验证每个字段的同时启动,因此您可以尝试查看is_valid() 以查看每个字段(序列化程序也是那里的字段)在验证期间是如何初始化的。您必须确定哪些嵌套字段是序列化程序,并将实例保存在父序列化程序中的某处
猜你喜欢
  • 1970-01-01
  • 2020-07-07
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-22
  • 2020-09-03
相关资源
最近更新 更多