Serializer 在 DRF 中负责:
from rest_framework import serializers
# 示例模型
class User(models.Model):
username = models.CharField(max_length=100)
email = models.EmailField()
is_active = models.BooleanField(default=True)
# 手动定义 Serializer
class UserSerializer(serializers.Serializer):
username = serializers.CharField(max_length=100)
email = serializers.EmailField()
is_active = serializers.BooleanField()
✅ 使用场景对比:
场景 |
|
|
---|---|---|
简单模型映射 | △ | ✅ |
复杂字段逻辑 | ✅ | △ |
快速原型开发 | △ | ✅ |
非模型数据 | ✅ | ❌ |
# 单个对象序列化
user = User.objects.get(id=1)
serializer = UserSerializer(user)
serializer.data # 输出:{'username': 'john', 'email': 'john@example.com', ...}
# 多个对象序列化
users = User.objects.all()
serializer = UserSerializer(users, many=True)
print(serializer.data)
data = {'username': 'alice', 'email': 'alice@example.com'}
serializer = UserSerializer(data=data)
if serializer.is_valid():
validated_data = serializer.validated_data # 获取验证后的数据
else:
errors = serializer.errors # 获取错误信息
字段类型 | 描述 | 示例 |
---|---|---|
BooleanField | 布尔值处理 | is_active = BooleanField(default=True) |
FloatField | 浮点数处理 | rating =FloatField(min_value=0.0, max_value=5.0) |
DecimalField | 高精度十进制数处理(适合金额) | price =DecimalField(max_digits=10, decimal_places=2) |
SlugField | Slug 格式字符串(字母、数字、下划线、连字符) | slug = SlugField(max_length=50) |
URLField | URL 格式验证 | website = URLField(allow_blank=True) |
UUIDField | UUID 格式字符串 | id = UUIDField(format='hex_verbose') |
JSONField | JSON 数据编码/解码 | metadata =JSONField(binary=False) |
字段类型 | 描述 | 示例 |
---|---|---|
StringRelatedField | 显示关联模型的 | author = StringRelatedField() |
HyperlinkedRelatedField | 生成超链接指向关联资源的 API 端点 | posts = HyperlinkedRelatedField(view_name='post-detail', many=True) |
SlugRelatedField | 通过 Slug 字段关联模型 | category = SlugRelatedField(slug_field='name', queryset=Category.objects.all()) |
HyperlinkedIdentityField | 生成当前对象的超链接 | url = HyperlinkedIdentityField(view_name='user-detail') |
NestedSerializer | 嵌套其他序列化器(非字段,但常用于关系处理) | comments = CommentSerializer(many=True) |
字段类型 | 描述 | 示例 |
---|---|---|
ImageField | 图片上传(继承自 | avatar = ImageField(max_length=100, allow_empty_file=False) |
DictField | 字典类型数据验证 | config = DictField(child=CharField()) |
HStoreField | PostgreSQL HStore 字段支持 | attributes=HStoreField() |
BinaryField | 二进制数据(如加密内容) | encrypted_data = BinaryField() |
字段类型 | 描述 | 示例 |
---|---|---|
DateField | 日期处理(不含时间) | birthday = DateField(format='%Y-%m-%d', input_formats='%Y-%m-%d') |
TimeField | 时间处理(不含日期) | start_time = TimeField(format='%H:%M:%S') |
DurationField | 时长处理(Python | duration = DurationField() |
字段类型 | 描述 | 示例 |
---|---|---|
HiddenField | 隐藏字段(通常用于自动填充数据,如当前用户) | user = HiddenField(default=CurrentUserDefault()) |
ReadOnlyField | 只读字段(仅用于序列化输出) | created_at = ReadOnlyField() |
MultipleChoiceField | 多选字段(配合 | tags = MultipleChoiceField(choices=TAG_CHOICES) |
ChoiceField | 单选字段 | status = ChoiceField(choices=STATUS_CHOICES) |
CustomField | 自定义字段(需继承 | 见下方示例 |
from rest_framework import serializers
class RGBColorField(serializers.Field):
"""
自定义字段:将 "#RRGGBB" 格式字符串转换为 RGB 元组
"""
def to_representation(self, value):
# 从数据库值转换为序列化输出
return {
'r': int(value[1:3], 16),
'g': int(value[3:5], 16),
'b': int(value[5:7], 16)
}
def to_internal_value(self, data):
# 从客户端输入转换为数据库存储格式
hex_color = "#{:02x}{:02x}{:02x}".format(data['r'], data['g'], data['b'])
return hex_color
class ProductSerializer(serializers.Serializer):
color = RGBColorField()
DecimalField
,URL 用 URLField
)SlugRelatedField
替代 PrimaryKeyRelatedField
提升可读性)ImageField
)HiddenField
自动填充当前用户)参数名 | 作用描述 | 适用字段类型 | 示例 |
---|---|---|---|
required | 是否必填(默认 True) | 所有字段 | email = EmailField(required=False) |
default | 默认值(支持函数或可调用对象) | 所有字段 | created = DateTimeField(default=timezone.now) |
allow_null | 是否允许 None 值(默认 False) | 所有字段 | middle_name = CharField(allow_null=True) |
source | 指定模型字段名或方法名 | 所有字段 | full_name = CharField(source='get_full_name') |
validators | 自定义验证器列表 | 所有字段 | age = IntegerField(validators=validate_age_range) |
error_messages | 覆盖默认错误信息 | 所有字段 | name = CharField(error_messages={'blank': '姓名不能为空'}) |
style | 控制 HTML 表单渲染样式 | 所有字段 | password = CharField(style={'input_type': 'password'}) |
read_only | 字段仅用于序列化输出(默认 False) | 所有字段 | id = IntegerField(read_only=True) |
write_only | 字段仅用于反序列化输入(默认 False) | 所有字段 | password = CharField(write_only=True) |
label | 字段的友好名称(用于表单和文档) | 所有字段 | email = EmailField(label='电子邮箱') |
help_text | 字段的帮助说明(用于表单和文档) | 所有字段 | content = CharField(help_text='请输入文章内容') |
initial | 表单中字段的初始值 | 所有字段 | quantity = IntegerField(initial=1) |
allow_blank | 允许空字符串(默认 False,仅 CharField 等文本字段有效) | 文本字段 | bio = CharField(allow_blank=True) |
trim_whitespace | 自动去除输入值的首尾空格(默认 True,仅 CharField 有效) | 文本字段 | title = CharField(trim_whitespace=False) |
min_length | 最小长度限制 | 文本/列表字段 | username = CharField(min_length=3) |
max_length | 最大长度限制 | 文本/列表字段 | password = CharField(max_length=128) |
min_value | 最小值限制 | 数值字段 | age = IntegerField(min_value=0) |
max_value | 最大值限制 | 数值字段 | score = IntegerField(max_value=100) |
read_only=True
: 字段仅用于输出(如创建时间、ID,用户无法提交修改)write_only=True
: 字段仅用于输入(如密码确认字段,用户无法读取)class UserSerializer(serializers.Serializer):
id = IntegerField(read_only=True) # 用户只能读取,无法提交json修改
password = CharField(write_only=True) # 用户只能写入,程序不会响应给用户password数据
CharField
、EmailField
)class CommentSerializer(serializers.Serializer):
content = CharField(
allow_blank=False, # 禁止空字符串
trim_whitespace=True # 自动去除首尾空格
)
IntegerField
、FloatField
、DecimalField
class ProductSerializer(serializers.Serializer):
price = DecimalField(
max_digits=10,
decimal_places=2,
min_value=0.01, # 价格必须大于 0
max_value=999999.99
)
class UserSerializer(serializers.Serializer):
username = CharField(
min_length=3,
error_messages={
'min_length': '用户名至少需要 {min_length} 个字符', # 支持格式化
'required': '用户名不能为空'
}
)
from rest_framework import serializers
from django.utils import timezone
class ArticleSerializer(serializers.Serializer):
# 基础参数
title = serializers.CharField(
max_length=100,
label="标题",
help_text="请输入文章标题",
error_messages={'blank': '标题不能为空'}
)
# 时间字段
created_at = serializers.DateTimeField(
read_only=True,
default=timezone.now
)
# 数值字段
views = serializers.IntegerField(
min_value=0,
default=0,
help_text="阅读次数"
)
# 关联字段
author = serializers.PrimaryKeyRelatedField(
queryset=User.objects.all(),
write_only=True # 只允许输入作者ID,输出时不显示
)
# 自定义验证
def validate_title(self, value):
if 'test' in value.lower():
raise serializers.ValidationError("标题不能包含敏感词")
return value
required
、default
)allow_blank
(仅字符串字段)、min_value
(仅数值字段)read_only
/write_only
分离输入输出逻辑error_messages
提升错误信息的可读性validators
实现复杂业务规则验证class OrderSerializer(serializers.Serializer):
product_id = serializers.IntegerField()
quantity = serializers.IntegerField(min_value=1)
# 字段级验证
def validate_quantity(self, value):
if value > 100:
raise serializers.ValidationError("单次购买不能超过100件")
return value
# 对象级验证
def validate(self, data):
if data['product'].stock < data['quantity']:
raise serializers.ValidationError("库存不足")
return data
# 使用独立验证器
discount_code = serializers.CharField(validators=[validate_discount_code])
create()
和 update()
class UserSerializer(serializers.Serializer):
# ...字段定义...
def create(self, validated_data):
return User.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.username = validated_data.get('username', instance.username)
instance.email = validated_data.get('email', instance.email)
instance.save()
return instance
# 创建新对象
serializer = UserSerializer(data=data)
if serializer.is_valid():
user = serializer.save() # 调用 create()
# 更新对象
user = User.objects.get(id=1)
serializer = UserSerializer(user, data=data)
if serializer.is_valid():
updated_user = serializer.save() # 调用 update()
class DynamicUserSerializer(serializers.Serializer):
def __init__(self, *args, **kwargs):
# 根据上下文隐藏敏感字段
fields = kwargs.pop('fields', None)
super().__init__(*args, **kwargs)
if fields is not None:
allowed = set(fields)
existing = set(self.fields)
for field_name in existing - allowed:
self.fields.pop(field_name)
class ProfileSerializer(serializers.Serializer):
address = serializers.CharField()
class UserDetailSerializer(serializers.Serializer):
username = serializers.CharField()
profile = ProfileSerializer() # 嵌套序列化器
is_valid()
write_only=True
# 使用 partial=True
serializer = UserSerializer(instance, data={'email': 'new@example.com'}, partial=True)
用于完全自定义输出格式:
def to_representation(self, instance):
data = super().to_representation(instance)
data['status'] = 'active' if instance.is_active else 'inactive'
return data
select_related
/prefetch_related
避免 N+1 查询help_text
参数生成 API 文档原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。