如何从父序列化器类中获取嵌套序列化器字段的值?
解决嵌套序列化器字段取值问题
问题分析
你需要在反序列化时让SerializerB的field_3从父序列化器SerializerA的field_1取值,但之前的__init__方法无法正常工作,核心原因有两点:
- 若输入JSON中未提供
field_2对应的内容,data会被设为DRF的empty标记,无法进入判断分支; - 代码中两次调用父类
__init__,第二次调用会覆盖第一次修改后的data,导致操作无效。
可行解决方案
方案一:在SerializerB的validate方法中直接取值
利用序列化器的parent属性获取父序列化器的原始输入数据,在验证阶段为field_3赋值:
class SerializerB(BaseSerializer): field_3 = serializers.IntegerField() def validate(self, data): # 从父序列化器的原始输入中获取field_1的值 field_1_value = self.parent.initial_data.get('field_1') # 将值注入当前字段数据 data['field_3'] = field_1_value return data
方案二:在SerializerA的to_internal_value中预处理数据
在父序列化器解析阶段,直接把field_1的值注入到field_2的输入数据中:
class SerializerA(BaseSerializer): field_1 = serializers.IntegerField() field_2 = SerializerB() def to_internal_value(self, data): # 先执行父类的解析逻辑,确保field_1已被处理 internal_data = super().to_internal_value(data) # 获取field_1的验证后的值 field_1_value = internal_data['field_1'] # 为field_2的解析数据添加field_3 if 'field_2' not in internal_data: internal_data['field_2'] = {} internal_data['field_2']['field_3'] = field_1_value return internal_data
方案三:通过context传递值
在父序列化器初始化时将field_1的值传入子序列化器的上下文,再在子序列化器中使用:
class SerializerA(BaseSerializer): field_1 = serializers.IntegerField() field_2 = SerializerB() def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 仅在反序列化时传递field_1的值到子序列化器上下文 if hasattr(self, 'initial_data'): self.fields['field_2'].context['field_1_value'] = self.initial_data.get('field_1') class SerializerB(BaseSerializer): field_3 = serializers.IntegerField() def validate(self, data): data['field_3'] = self.context.get('field_1_value') return data
内容的提问来源于stack exchange,提问作者Karthik
相关产品推荐
相关产品推荐

