You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DRF中如何获取嵌套序列化器字段执行自定义校验?

问题原因

你在DetailSerializer中将master嵌套序列化器设置为read_only=True,该字段仅会在序列化返回响应时生效,不会处理前端提交的反序列化输入,因此validate方法的attrs参数中不会包含master相关数据,自然无法直接获取date_signed字段。

解决方案

保留原有只读嵌套序列化器用于返回关联主表完整信息,额外新增一个可写的外键主键字段接收前端提交的关联MasterID,在校验逻辑中通过主键查询获取Master实例即可拿到date_signed字段,同时兼容创建、更新两种业务场景。

完整修正后的序列化器代码
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from .models import Master, Detail

class MasterSerializer(serializers.ModelSerializer):
    class Meta:
        model = Master
        fields = ['id','date_signed','info1','info2']

class DetailSerializer(serializers.ModelSerializer):
    # 保留只读嵌套序列化器,用于返回响应时带出master完整信息
    master = MasterSerializer(read_only=True)
    # 新增可写外键字段,用于接收前端提交的master关联ID,仅在反序列化时生效
    master_id = serializers.PrimaryKeyRelatedField(
        queryset=Master.objects.all(),
        write_only=True,
        source='master' # 指定映射到模型的master字段
    )

    class Meta:
        model = Detail
        fields = ['id','master','master_id','date_start','date_end','info3','info4']

    def validate(self, attrs):
        # 兼容部分更新场景,优先取attrs中的新值,没有则取现有实例的值
        date_start = attrs.get('date_start', self.instance.date_start if self.instance else None)
        date_end = attrs.get('date_end', self.instance.date_end if self.instance else None)
        # 校验date_start早于date_end
        if date_start >= date_end:
            raise ValidationError('开始日期必须早于结束日期')
        
        # 获取master实例:优先取attrs中新提交的,没有则取现有实例关联的master
        master = attrs.get('master', self.instance.master if self.instance else None)
        # 校验master的date_signed早于detail的date_start
        if master.date_signed >= date_start:
            raise ValidationError('主表签署日期必须早于明细开始日期')
        
        return attrs
使用说明

前端提交创建/更新请求时,只需传master_id字段对应关联的Master主键即可,接口返回时会自动带出master嵌套的完整信息,无需额外处理。


内容的提问来源于stack exchange,提问作者theRoad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 14:54:00