如何用Marshmallow将模型字段序列化为嵌套结构

来源:Nodejs社区作者:俊华头衔:草根站长
导读:本期聚焦于小伙伴创作的《如何用Marshmallow将模型字段序列化为嵌套结构》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何用Marshmallow将模型字段序列化为嵌套结构》有用,将其分享出去将是对创作者最好的鼓励。

Marshmallow是Python生态中用于对象序列化与反序列化的常用库,在处理数据库模型、API数据交互等场景时,经常需要将多个关联的模型字段整合成嵌套的JSON结构,而不是扁平的字段集合,这样能更贴合前端的数据使用习惯,也能清晰体现数据之间的关联关系。

如何用Marshmallow将模型字段序列化为嵌套结构

Marshmallow基础序列化回顾

在使用嵌套结构之前,先了解Marshmallow的基础序列化逻辑。首先需要定义一个继承自Schema的类,在类中声明需要序列化的字段,然后将模型实例传入Schema的dump方法即可完成序列化。

比如我们有一个简单的用户模型,包含用户id、用户名两个基础字段,对应的基础序列化Schema如下:

from marshmallow import Schema, fields

# 模拟用户模型
class User:
    def __init__(self, user_id, username):
        self.user_id = user_id
        self.username = username

# 用户基础序列化Schema
class UserSchema(Schema):
    user_id = fields.Integer()
    username = fields.String()

# 使用Schema序列化
user = User(user_id=1, username="张三")
user_schema = UserSchema()
result = user_schema.dump(user)
print(result)  # 输出:{'user_id': 1, 'username': '张三'}

嵌套结构的核心实现方式

Marshmallow中实现嵌套结构的核心是fields.Nested字段,这个字段可以接收一个其他的Schema类,将对应Schema序列化得到的结果作为当前字段的值,从而实现字段的嵌套包装。

一对一嵌套场景

一对一嵌套是最常见的场景,比如用户和用户的详细信息是一对一的关系,用户详细信息包含年龄、手机号两个字段,我们希望序列化用户的时候,把详细信息作为用户的一个嵌套字段返回。

首先定义用户详细信息的Schema和用户模型:

from marshmallow import Schema, fields

# 模拟用户详细信息模型
class UserProfile:
    def __init__(self, age, phone):
        self.age = age
        self.phone = phone

# 模拟用户模型,包含用户基本信息和关联的详细信息
class User:
    def __init__(self, user_id, username, profile):
        self.user_id = user_id
        self.username = username
        self.profile = profile

# 用户详细信息Schema
class UserProfileSchema(Schema):
    age = fields.Integer()
    phone = fields.String()

# 用户Schema,使用Nested字段嵌套UserProfileSchema
class UserSchema(Schema):
    user_id = fields.Integer()
    username = fields.String()
    # 嵌套字段,值为UserProfileSchema的实例
    profile = fields.Nested(UserProfileSchema)

接下来测试序列化效果:

# 创建关联数据
profile = UserProfile(age=25, phone="13800138000")
user = User(user_id=1, username="张三", profile=profile)

user_schema = UserSchema()
result = user_schema.dump(user)
print(result)
# 输出:{'user_id': 1, 'username': '张三', 'profile': {'age': 25, 'phone': '13800138000'}}

一对多嵌套场景

一对多嵌套指的是一个主模型关联多个子模型,比如一个作者可以写多篇文章,我们希望序列化作者的时候,把所有文章的信息作为嵌套的列表字段返回。

实现方式和一对一类似,只需要在fields.Nested中添加many=True参数,表示这个字段对应的是多个子对象组成的列表。

from marshmallow import Schema, fields

# 模拟文章模型
class Article:
    def __init__(self, article_id, title, content):
        self.article_id = article_id
        self.title = title
        self.content = content

# 模拟作者模型,关联多篇文章
class Author:
    def __init__(self, author_id, name, articles):
        self.author_id = author_id
        self.name = name
        self.articles = articles

# 文章Schema
class ArticleSchema(Schema):
    article_id = fields.Integer()
    title = fields.String()
    content = fields.String()

# 作者Schema,嵌套文章列表
class AuthorSchema(Schema):
    author_id = fields.Integer()
    name = fields.String()
    # many=True表示articles是多个Article对象的列表
    articles = fields.Nested(ArticleSchema, many=True)

测试一对多嵌套的序列化效果:

# 创建文章数据
article1 = Article(article_id=1, title="Python基础", content="Python入门教程")
article2 = Article(article_id=2, title="Marshmallow教程", content="Marshmallow使用指南")
# 创建作者数据,关联两篇文章
author = Author(author_id=1, name="李四", articles=[article1, article2])

author_schema = AuthorSchema()
result = author_schema.dump(author)
print(result)
# 输出:{'author_id': 1, 'name': '李四', 'articles': [{'article_id': 1, 'title': 'Python基础', 'content': 'Python入门教程'}, {'article_id': 2, 'title': 'Marshmallow教程', 'content': 'Marshmallow使用指南'}]}

嵌套序列化的注意事项

  • 嵌套的Schema可以复用,比如多个不同的父Schema都可以嵌套同一个子Schema,不需要重复定义字段。
  • 如果嵌套的模型中某个字段不需要序列化,可以在子Schema中不包含该字段,Marshmallow会自动忽略模型中不存在于Schema的字段。
  • 如果嵌套层级过深,需要注意避免出现循环引用的问题,比如A嵌套B,B又嵌套A,这种情况下Marshmallow会抛出递归错误,需要合理设计嵌套层级。
  • 可以通过给fields.Nested传递dump_only=True参数,设置该嵌套字段只在序列化时生效,反序列化时忽略。

常见使用场景

嵌套序列化在API开发中使用非常广泛,比如电商系统中,订单模型可以嵌套商品列表、收货地址等子结构;博客系统中,评论模型可以嵌套评论用户的基础信息,不需要把用户的全部字段都返回,既减少了数据传输量,也让数据结构更清晰。

通过fields.Nested字段,Marshmallow可以灵活实现各种复杂的嵌套结构需求,开发者只需要根据数据关联关系定义好对应的Schema,就能快速完成模型字段的嵌套序列化工作。

Marshmallow序列化嵌套结构模型字段修改时间:2026-07-20 13:57:34

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。