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

如何让Marshmallow在序列化时抛出AttributeError及缺失属性异常?

解决Marshmallow序列化时缺少required字段不报错的问题

你遇到的这个情况其实是Marshmallow的默认行为:required=True参数只在反序列化(从字典/JSON转成对象)时生效,序列化(从对象转成JSON)时,框架只会尝试读取对象的属性,如果属性不存在就直接跳过该字段,不会主动抛出异常。这就是为什么你调用Foo().dumps(bar)返回空JSON,但直接访问bar.bar会触发AttributeError的原因。

要实现序列化时缺少必填字段就抛出异常,有几种实用的方法:

方法一:用post_dump钩子校验序列化结果

在Schema里添加post_dump装饰器,序列化完成后检查必填字段是否存在,不存在就抛出ValidationError:

import marshmallow
from marshmallow.decorators import post_dump

class Foo(marshmallow.Schema):
    bar = marshmallow.fields.Str(required=True)

    @post_dump
    def enforce_required_fields(self, serialized_data, **kwargs):
        # 检查所有required=True的字段是否都在序列化结果里
        for field_name, field in self.fields.items():
            if field.required and field_name not in serialized_data:
                raise marshmallow.ValidationError(f"Missing required field: {field_name}")
        return serialized_data

class Bar:
    pass

bar = Bar()
# 现在执行这行代码会抛出ValidationError
Foo().dumps(bar)

这个方法的好处是可以一次性校验所有必填字段,不用逐个字段处理。

方法二:自定义严格校验的字段

如果只想针对特定字段做严格校验,可以自定义字段类,重写_serialize方法,在读取属性时捕获AttributeError并转为Marshmallow的校验异常:

import marshmallow

class StrictRequiredStr(marshmallow.fields.Str):
    def _serialize(self, value, attr_name, obj, **kwargs):
        try:
            # 主动尝试获取对象属性,不存在则抛出AttributeError
            value = getattr(obj, attr_name)
        except AttributeError as e:
            # 转为Marshmallow的ValidationError,保持异常风格统一
            raise marshmallow.ValidationError(f"Required field '{attr_name}' is missing from object") from e
        # 调用父类的序列化逻辑处理正常情况
        return super()._serialize(value, attr_name, obj, **kwargs)

class Foo(marshmallow.Schema):
    # 使用自定义的严格字段
    bar = StrictRequiredStr(required=True)

class Bar:
    pass

bar = Bar()
# 执行后会抛出ValidationError
Foo().dumps(bar)

方法三:重写Schema的dump方法

如果你想让整个Schema的序列化都强制校验必填字段,可以重写Schema的dump方法,在序列化前先检查对象的属性:

import marshmallow

class StrictSchema(marshmallow.Schema):
    def dump(self, obj, **kwargs):
        # 遍历所有required=True的字段,检查对象是否有对应属性
        for field_name, field in self.fields.items():
            if field.required and not hasattr(obj, field_name):
                raise marshmallow.ValidationError(f"Object missing required attribute: {field_name}")
        return super().dump(obj, **kwargs)

# 继承自定义的StrictSchema
class Foo(StrictSchema):
    bar = marshmallow.fields.Str(required=True)

class Bar:
    pass

bar = Bar()
# 执行后抛出ValidationError
Foo().dumps(bar)

这个方法适合你有多个Schema都需要严格校验的场景,只需要继承StrictSchema即可,不用重复写校验逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:18:54