DRF(Django REST Framework)的序列化器是连接数据库模型与 API 响应的核心桥梁,ModelSerializer作为Serializer的子类,能自动生成与模型字段对应的序列化字段,避免手动定义每个属性,同时支持自定义字段、数据验证和关联关系处理,是实际开发中使用率超过 90% 的序列化方案。
以图书与作者的关联模型为例,优化后的序列化器不仅能简化代码,还能通过嵌套序列化、字段权限控制等功能,满足复杂的 API 数据返回需求:
# models.py
from django.db import models
# 外键关联:on_delete=models.CASCADE表示删除作者时,关联的图书也会被删除
author = models.ForeignKey(
Author,
on_delete=models.CASCADE,
related_name="books", # 反向查询别名,可通过author.books获取作者的所有图书
verbose_name=_("作者")
)
price = models.DecimalField(
_("价格"),
max_digits=10, # 总位数
decimal_places=2, # 小数位数
help_text="图书的销售价格,保留两位小数"
)
is_published = models.BooleanField(_("是否出版"), default=False)
created_at = models.DateTimeField(_("创建时间"), auto_now_add=True)
class Meta:
verbose_name = _("图书")
verbose_name_plural = _("图书列表")
indexes = [
# 为常用查询字段添加索引,提升查询效率
models.Index(fields=["title"]),
models.Index(fields=["author", "is_published"])
]# serializers.py
from rest_framework import serializers
# 6. 字段级验证:针对单个字段进行合法性检查
def validate_title(self, value):
"""验证书名长度不小于5个字符,且不包含特殊符号"""
if len(value) < 5:
raise serializers.ValidationError(_("书名长度不能少于5个字符"))
if any(char in '!@#$%^&*()' for char in value):
raise serializers.ValidationError(_("书名不能包含特殊符号"))
return value
# 7. 对象级验证:针对多个字段的关联验证(如出版状态与价格的关系)
def validate(self, data):
"""若图书已出版,价格不能低于10元"""
if data.get("is_published") and data.get("price") < 10:
raise serializers.ValidationError(_("已出版图书的价格不能低于10元"))
return data
# 8. 重写创建/更新方法:添加额外业务逻辑(如记录操作日志)
def create(self, validated_data):
# 获取当前登录用户(需在视图中配置认证)
user = self.context["request"].user
# 创建图书记录
book = Book.objects.create(**validated_data)
# 记录操作日志(实际项目可使用Django信号或日志模块)
print(f"用户{user.username}创建了图书:{book.title}")
return book在视图中使用该序列化器时,可根据请求类型自动适配字段权限:
- GET 请求:返回author_info、price_tag等只读字段,方便前端展示;
- POST/PUT 请求:仅接收title、price、author等可写字段,且经过验证逻辑确保数据合法性。

