一、引言:什么是 Django 序列化?

在 Web 开发中,序列化(Serialization) 是指将复杂的数据结构(如数据库模型对象)转换为可传输的格式(如 JSON、XML、YAML 等),以便在客户端与服务器之间进行通信。

Django 提供了多种序列化机制,帮助开发者轻松地将模型数据转换为结构化数据格式,常用于构建 RESTful API、数据导出、缓存等场景。

本文将深入讲解 Django 的序列化机制,涵盖:

  • Django 内置序列化器(serializers
  • Django REST Framework(DRF)序列化器
  • 自定义字段与验证逻辑
  • 嵌套关系处理
  • 性能优化建议

二、Django 内置序列化器详解

Django 自带了一个简单的序列化模块 django.core.serializers,支持 JSON、XML、YAML 等格式。

1. 使用示例

from django.core import serializers
from myapp.models import Book# 序列化为 JSON
books = Book.objects.all()
json_data = serializers.serialize("json", books)# 反序列化
for obj in serializers.deserialize("json", json_data):obj.save()

2. 输出格式说明

输出的 JSON 数据包含模型名称、主键和字段值:

[{"model": "myapp.book","pk": 1,"fields": {"title": "Django 入门","author": "张三","published": "2023-01-01"}}
]

3. 优点与限制

优点

缺点

简单易用

无法自定义字段名

支持反序列化

不支持嵌套关系

适合数据迁移或导出

不适合构建 REST API


三、Django REST Framework(DRF)序列化器详解

在构建 RESTful API 时,Django REST Framework(DRF) 提供了更强大、灵活的序列化器系统,支持字段验证、嵌套关系、分页、自定义渲染等。

1. 安装 DRF

pip install djangorestframework

settings.py 中添加:

INSTALLED_APPS += ['rest_framework']

2. 定义一个基础序列化器

from rest_framework import serializers
from myapp.models import Bookclass BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = '__all__'

3. 序列化单个对象或查询集

book = Book.objects.get(id=1)
serializer = BookSerializer(book)
print(serializer.data)books = Book.objects.all()
serializer = BookSerializer(books, many=True)
print(serializer.data)

输出示例:

{"id": 1,"title": "Django 入门","author": "张三","published": "2023-01-01"
}

四、自定义字段与验证逻辑

1. 自定义字段类型

class BookSerializer(serializers.ModelSerializer):title_upper = serializers.SerializerMethodField()class Meta:model = Bookfields = ['id', 'title', 'title_upper', 'author', 'published']def get_title_upper(self, obj):return obj.title.upper()

2. 添加验证逻辑

class BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = ['id', 'title', 'author', 'published']def validate_title(self, value):if len(value) < 3:raise serializers.ValidationError("书名必须大于3个字符")return value

3. 全局验证

def validate(self, data):if data['title'] == data['author']:raise serializers.ValidationError("书名不能与作者相同")return data

五、处理嵌套关系(Nested Relationships)

1. 外键关系

class AuthorSerializer(serializers.ModelSerializer):class Meta:model = Authorfields = ['id', 'name']class BookSerializer(serializers.ModelSerializer):author = AuthorSerializer()class Meta:model = Bookfields = ['id', 'title', 'author', 'published']

2. 反向关系(Related Field)

class AuthorSerializer(serializers.ModelSerializer):books = BookSerializer(many=True, read_only=True)class Meta:model = Authorfields = ['id', 'name', 'books']

3. 可写嵌套关系

默认情况下,嵌套关系是只读的。如需写入,需重写 create()update() 方法。

class BookSerializer(serializers.ModelSerializer):author = AuthorSerializer()class Meta:model = Bookfields = ['id', 'title', 'author', 'published']def create(self, validated_data):author_data = validated_data.pop('author')author, created = Author.objects.get_or_create(**author_data)return Book.objects.create(author=author, **validated_data)

六、性能优化:减少数据库查询

1. 使用 select_related()prefetch_related()

books = Book.objects.select_related('author').all()
serializer = BookSerializer(books, many=True)

2. 避免 N+1 查询问题

使用 DRF 的 Prefetchdepth 选项优化嵌套关系查询。

class BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = '__all__'depth = 1  # 自动展开外键关系(不推荐用于复杂结构)

3. 使用缓存减少重复查询

from django.core.cache import cachedef get_books():books = cache.get('books_list')if not books:books = Book.objects.all()cache.set('books_list', books, 60 * 15)  # 缓存15分钟return books

七、DRF 序列化器高级用法

1. HyperlinkedModelSerializer(生成 API 链接)

class BookSerializer(serializers.HyperlinkedModelSerializer):class Meta:model = Bookfields = ['url', 'title', 'author', 'published']

2. 使用 to_representation() 自定义输出

class BookSerializer(serializers.ModelSerializer):def to_representation(self, instance):data = super().to_representation(instance)data['custom_field'] = f"书籍:{instance.title}"return data

3. 使用 to_internal_value() 自定义输入

class BookSerializer(serializers.ModelSerializer):def to_internal_value(self, data):data['title'] = data['title'].strip()return super().to_internal_value(data)

八、DRF 序列化器 vs Django 原生序列化器对比

功能

Django 原生序列化器

DRF 序列化器

支持 JSON、XML、YAML

✅(默认 JSON)

支持反序列化

支持字段验证

支持嵌套关系

支持自定义字段

支持 REST API 构建

支持分页

支持性能优化(如 select_related)

九、最佳实践建议

场景

建议

数据迁移、导出

使用 Django 原生序列化器

构建 REST API

使用 DRF 序列化器

高性能需求

使用 select_related()

prefetch_related()

字段验证

使用 DRF 序列化器的 validate()

方法

嵌套结构

使用 SerializerMethodField

Prefetch

安全性

使用 read_only_fields

extra_kwargs

控制字段权限

代码复用

抽取公共字段、继承 ModelSerializer

实现复用


十、总结

Django 提供了两种强大的序列化机制:

  • 原生序列化器:适合数据导出、迁移等场景;
  • DRF 序列化器:适合构建 RESTful API、支持字段验证、嵌套关系、自定义字段等高级功能。

掌握序列化机制,是构建高效、可维护、安全的 Django Web 应用的重要基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/92236.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/92236.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/92236.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

茶叶蛋大冒险小游戏流量主微信抖音小程序开源

游戏特点 响应式设计&#xff1a;完美适配各种移动设备屏幕尺寸 直观的触摸控制&#xff1a;左右滑动屏幕控制茶叶蛋移动 中式风格元素&#xff1a; 茶叶蛋角色带有裂纹纹理和可爱表情 筷子、蒸笼等中式厨房元素作为障碍物 八角、茶叶等香料作为收集物 锅底火焰动画效果 游戏机…

区分邮科工业交换机与路由器

在这个数字化的时代&#xff0c;我们每天都在享受着互联网带来的便利。无论是工作还是娱乐&#xff0c;网络已经成为我们生活中不可或缺的一部分。然而&#xff0c;在这个看似简单的背后&#xff0c;隐藏着两个至关重要的设备——邮科工业交换机和路由器。它们就像网络世界的双…

【数据结构入门】数组和链表的OJ题(2)

目录 1.回文链表 分析&#xff1a; 代码&#xff1a; 2.相交链表 分析&#xff1a; 代码&#xff1a; 3.环形链表 分析&#xff1a; 代码&#xff1a; 面试提问&#xff1a; 4.环形链表II 分析1&#xff1a; 分析2&#xff1a; 代码&#xff1a; 5.随机链表的复…

文件包含篇

web78 第一题filter伪协议直接读源码即可 ?filephp://filter/convert.base64-encode/resourceflag.php web79 flag.php的php无法用大小写绕过&#xff0c;所以用Php://input只读流 import requests url "http://fadb524a-f22d-4747-a35c-82f71e84bba7.challenge.ctf.sho…

互作蛋白组学技术对比:邻近标记与传统IP-MS、Pull down-MS优势对比

在生命科学领域&#xff0c;蛋白质间的相互作用构成了生命活动的核心网络&#xff0c;驱动着信号传导、基因调控、代谢途径等关键过程。为了绘制这幅复杂的“分子互作地图”&#xff0c;科学家们开发了多种技术&#xff0c;其中免疫共沉淀结合质谱&#xff08;IP-MS&#xff09…

(ZipList入门笔记一)ZipList的节点介绍

ZipList是 Redis 中一种非常紧凑、节省内存的数据结构 Ziplist&#xff08;压缩列表&#xff09; 的内部内存布局。它被用于存储元素较少的 List、Hash 和 Zset。 下面我们来详细介绍每一个节点的含义&#xff1a; 1. zlbytes (ziplist bytes) 含义&#xff1a; 整个压缩列…

Unix 发展史概览

这里是一个简明清晰的 Unix 发展史概览&#xff0c;涵盖从起源到现代的重要节点和演变过程。Unix 发展史概览 1. Unix 起源&#xff08;1969年&#xff09; 贝尔实验室&#xff1a;Ken Thompson 和 Dennis Ritchie 开发出 Unix 操作系统。最初设计目标&#xff1a;简洁、可移植…

基于coze studio开源框架二次定制开发教程

目录 一、 项目介绍 1.1 什么是Coze Studio 1.2 功能清单 1.3对比商业版本 二、 功能定开说明 2.1 技术栈简介 2.2 项目架构

RHCE认证题解

考前说明请勿更改 IP 地址。DNS 解析完整主机名&#xff0c;同时也解析短名称。• 所有系统的 root 密码都是 redhat• Ansible 控制节点上已创建用户账户 devops。可以使用 ssh 访问• 所需的所有镜像保存在镜像仓库 utility.lab.example.compodman 可使用下述账号登录使用 用…

调用com对象的坑

1、谏言 最近我在弄64位调用32位dll的问题&#xff0c;在几种IPC之间&#xff0c;最后考虑了调用COM 毕竟我们只在windows平台 2、第一坑–修改编译后都需要重新注册&#xff0c;注册表 一直以为只需要编译就好了&#xff0c;结果调用没反应、报错什么的&#xff0c;需要先撤销…

【Python】PyQt 实现 TreeWidget 多级联动选择逻辑,打造素材搜索自定义树形控件!

在开发自己的写作素材管理工具时,我遇到了一个非常典型但又略显棘手的 UI 问题: 💡 如何实现一个“可自由勾选分类标签”的树形结构界面,支持父子节点自动联动勾选,提升用户体验? 虽然 PyQt 的 QTreeWidget 是构建多层分类结构的好帮手,但默认却不具备父子节点的自动级…

27-数据仓库与Apache Hive-2

1.数仓开发语言概述 理论上来说&#xff0c;任何一款编程语言只要具备读写数据、处理数据的能力&#xff0c;都可以用于数仓的开发。比如大家耳熟能详的C、java、Python等&#xff1b; 关键在于编程语言是否易学、好用、功能是否强大。遗憾的是上面所列出的C、Python等编程语言…

软件测试——接口自动化

测试中的自动化分为两类&#xff1a; 1.ui自动化&#xff08;web、移动端&#xff09;2.接口自动化 前面的博客中&#xff0c;我们已经讲解了web端的ui自动化&#xff0c;感兴趣的同学可以去看看&#xff1a;软件测试——自动化测试常见函数_自动化测试代码编写-CSDN博客 今…

Flask一个用户同时只能在一处登录实现

场景&#xff1a;web页面如果多人用同一账号同时登录操作&#xff0c;可能会导致数据等的混乱甚至出现故障。并且可能损害开发者的利益。为此&#xff0c;本篇文章就讲下如何实现同一账户同时仅能一个地方登录操作。 思路&#xff1a;1. 用户登陆时生成token&#xff08;uuid.u…

联发科芯片组曝高危漏洞:越界写入缺陷危及智能手机与物联网设备安全

漏洞概况全球领先的芯片组制造商联发科&#xff08;MediaTek&#xff09;近日发布最新产品安全公告&#xff0c;披露了影响其智能手机、物联网设备及其他嵌入式系统芯片的多项安全漏洞。高危漏洞分析CVE-2025-20696 作为公告披露的首个且最严重的漏洞&#xff0c;该高危缺陷源于…

Android与Flutter混合开发:页面跳转与通信完整指南

Android与Flutter混合开发&#xff1a;页面跳转与通信完整指南 一、Android跳转Flutter页面的实现方式 1. 基础跳转方法 &#xff08;1&#xff09;使用全新引擎跳转&#xff08;每次新建&#xff09; startActivity(FlutterActivity.withNewEngine().initialRoute("/home…

Web存储技术详解:sessionStorage、localStorage与Cookie

一、核心特性对比特性CookielocalStoragesessionStorage存储大小4KB左右5-10MB5-10MB生命周期可设置过期时间永久存储&#xff08;除非手动清除&#xff09;会话期间有效&#xff08;标签页关闭即清除&#xff09;作用域同源的所有窗口同源的所有窗口仅当前标签页自动发送每次H…

3. 为什么 0.1 + 0.2 != 0.3

总结 底层是二进制实现概述 在 JavaScript 中&#xff0c;0.1 0.2 的结果并不是精确的 0.3&#xff0c;而是 0.30000000000000004。这个现象并不是 JavaScript 的“bug”&#xff0c;而是由于浮点数在计算机底层的二进制表示方式导致的精度丢失问题。一、计算机如何表示小数&a…

股票数据接口哪家好?专业评测各主流接口的优势与不足

Python股票接口实现查询账户&#xff0c;提交订单&#xff0c;自动交易&#xff08;1&#xff09; Python股票程序交易接口查账&#xff0c;提交订单&#xff0c;自动交易&#xff08;2&#xff09; 股票量化&#xff0c;Python炒股&#xff0c;CSDN交流社区 >>> 股票…

如何用分布式架构视角理解宇宙稳定性?从精细调参到微服务的类比思考

在调试一段多线程分布式代码时&#xff0c;我忽然意识到一个不合理的事实&#xff1a;为什么现实世界这么稳定&#xff1f;为什么没有“宇宙蓝屏”或“感知崩溃”&#xff1f;为什么每天醒来&#xff0c;我们还能看到同样的物理规律、感知同一个自我&#xff1f;站在程序员的角…