DRF 序列化器基础 #
一、什么是序列化器 #
1.1 序列化器的定义 #
序列化器(Serializer)是DRF的核心组件,负责在复杂数据类型(如Django模型实例)与Python原生数据类型(如字典、列表)之间进行转换。
text
┌─────────────────┐ ┌─────────────────┐
│ 复杂数据类型 │ │ Python原生 │
│ (模型实例) │◀──── 序列化器 ────▶│ 数据类型 │
│ │ │ (dict, list) │
└─────────────────┘ └─────────────────┘
│ │
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ 数据库 │ │ JSON响应 │
└─────────────────┘ └─────────────────┘
1.2 序列化器的核心功能 #
| 功能 | 说明 |
|---|---|
| 序列化 | 将模型实例转换为JSON格式 |
| 反序列化 | 将JSON数据转换为Python对象 |
| 数据验证 | 验证输入数据的合法性 |
| 字段控制 | 控制哪些字段可以被访问 |
二、基本序列化器 #
2.1 定义序列化器 #
创建一个基本的序列化器:
python
from rest_framework import serializers
class ArticleSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
title = serializers.CharField(max_length=200)
content = serializers.CharField()
author = serializers.CharField(max_length=100)
created_at = serializers.DateTimeField(read_only=True)
is_published = serializers.BooleanField(default=False)
2.2 序列化数据 #
将模型实例序列化为JSON:
python
from .models import Article
article = Article.objects.get(pk=1)
serializer = ArticleSerializer(article)
print(serializer.data)
# {'id': 1, 'title': '文章标题', 'content': '内容', ...}
2.3 序列化查询集 #
序列化多个对象:
python
articles = Article.objects.all()
serializer = ArticleSerializer(articles, many=True)
print(serializer.data)
# [{'id': 1, ...}, {'id': 2, ...}, ...]
三、反序列化 #
3.1 反序列化数据 #
将JSON数据反序列化为Python对象:
python
data = {
'title': '新文章',
'content': '文章内容',
'author': '张三'
}
serializer = ArticleSerializer(data=data)
if serializer.is_valid():
print(serializer.validated_data)
else:
print(serializer.errors)
3.2 实现create方法 #
保存新数据需要实现create方法:
python
class ArticleSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
title = serializers.CharField(max_length=200)
content = serializers.CharField()
author = serializers.CharField(max_length=100)
def create(self, validated_data):
return Article.objects.create(**validated_data)
使用:
python
serializer = ArticleSerializer(data=data)
if serializer.is_valid():
article = serializer.save()
3.3 实现update方法 #
更新数据需要实现update方法:
python
class ArticleSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
title = serializers.CharField(max_length=200)
content = serializers.CharField()
author = serializers.CharField(max_length=100)
def create(self, validated_data):
return Article.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.title = validated_data.get('title', instance.title)
instance.content = validated_data.get('content', instance.content)
instance.author = validated_data.get('author', instance.author)
instance.save()
return instance
使用:
python
article = Article.objects.get(pk=1)
serializer = ArticleSerializer(article, data=data)
if serializer.is_valid():
article = serializer.save()
四、字段类型 #
4.1 常用字段类型 #
| 字段类型 | 说明 | 对应Python类型 |
|---|---|---|
| IntegerField | 整数 | int |
| CharField | 字符串 | str |
| BooleanField | 布尔值 | bool |
| FloatField | 浮点数 | float |
| DecimalField | 高精度小数 | Decimal |
| DateTimeField | 日期时间 | datetime |
| DateField | 日期 | date |
| EmailField | 邮箱 | str |
| URLField | URL | str |
| ListField | 列表 | list |
| DictField | 字典 | dict |
4.2 字段示例 #
python
class ExampleSerializer(serializers.Serializer):
id = serializers.IntegerField()
name = serializers.CharField(max_length=100)
email = serializers.EmailField()
website = serializers.URLField(required=False)
age = serializers.IntegerField(min_value=0, max_value=150)
score = serializers.FloatField()
price = serializers.DecimalField(max_digits=10, decimal_places=2)
is_active = serializers.BooleanField(default=True)
created_at = serializers.DateTimeField()
birth_date = serializers.DateField()
tags = serializers.ListField(child=serializers.CharField())
metadata = serializers.DictField()
4.3 关系字段 #
处理模型关系:
python
class CommentSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
article = serializers.PrimaryKeyRelatedField(queryset=Article.objects.all())
author = serializers.CharField(max_length=100)
content = serializers.CharField()
created_at = serializers.DateTimeField(read_only=True)
五、字段参数 #
5.1 通用参数 #
python
class ArticleSerializer(serializers.Serializer):
title = serializers.CharField(
max_length=200, # 最大长度
min_length=1, # 最小长度
required=True, # 是否必需
allow_null=False, # 是否允许null
allow_blank=False, # 是否允许空字符串
default='', # 默认值
read_only=False, # 是否只读
write_only=False, # 是否只写
help_text='文章标题', # 帮助文本
label='标题', # 标签
error_messages={ # 自定义错误消息
'required': '标题不能为空',
'max_length': '标题不能超过200个字符'
}
)
5.2 参数说明 #
| 参数 | 说明 |
|---|---|
| read_only | 只能序列化输出,不能反序列化输入 |
| write_only | 只能反序列化输入,不能序列化输出 |
| required | 反序列化时是否必需 |
| default | 默认值 |
| allow_null | 是否允许None值 |
| allow_blank | 是否允许空字符串 |
| validators | 自定义验证器列表 |
| error_messages | 自定义错误消息 |
5.3 read_only和write_only #
python
class UserSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
username = serializers.CharField()
password = serializers.CharField(write_only=True)
created_at = serializers.DateTimeField(read_only=True)
read_only=True:只在响应中返回,不接受输入write_only=True:只接受输入,不在响应中返回
六、数据验证 #
6.1 基本验证 #
python
serializer = ArticleSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
else:
return Response(serializer.errors, status=400)
6.2 访问验证数据 #
python
if serializer.is_valid():
print(serializer.validated_data)
print(serializer.validated_data['title'])
6.3 字段级验证 #
python
class ArticleSerializer(serializers.Serializer):
title = serializers.CharField(max_length=200)
def validate_title(self, value):
if '敏感词' in value:
raise serializers.ValidationError('标题包含敏感词')
return value
6.4 对象级验证 #
python
class ArticleSerializer(serializers.Serializer):
title = serializers.CharField(max_length=200)
content = serializers.CharField()
start_date = serializers.DateField()
end_date = serializers.DateField()
def validate(self, data):
if data['start_date'] > data['end_date']:
raise serializers.ValidationError('开始日期不能晚于结束日期')
return data
6.5 自定义验证器 #
python
def validate_title_length(value):
if len(value) < 5:
raise serializers.ValidationError('标题至少需要5个字符')
return value
class ArticleSerializer(serializers.Serializer):
title = serializers.CharField(validators=[validate_title_length])
七、嵌套序列化 #
7.1 一对多关系 #
python
class CommentSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
content = serializers.CharField()
author = serializers.CharField()
class ArticleSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
title = serializers.CharField()
comments = CommentSerializer(many=True, read_only=True)
7.2 外键关系 #
python
class CategorySerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
name = serializers.CharField()
class ArticleSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
title = serializers.CharField()
category = CategorySerializer()
八、序列化器在视图中的使用 #
8.1 在函数视图中使用 #
python
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
@api_view(['GET', 'POST'])
def article_list(request):
if request.method == 'GET':
articles = Article.objects.all()
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = ArticleSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
8.2 在类视图中使用 #
python
from rest_framework.views import APIView
class ArticleList(APIView):
def get(self, request):
articles = Article.objects.all()
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data)
def post(self, request):
serializer = ArticleSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
九、序列化器上下文 #
9.1 传递上下文 #
python
serializer = ArticleSerializer(
article,
context={'request': request}
)
9.2 在序列化器中使用上下文 #
python
class ArticleSerializer(serializers.Serializer):
title = serializers.CharField()
def get_author_name(self, obj):
request = self.context.get('request')
if request and request.user.is_authenticated:
return request.user.username
return '匿名'
十、动态字段 #
10.1 动态排除字段 #
python
class DynamicFieldsSerializer(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 ArticleSerializer(DynamicFieldsSerializer):
id = serializers.IntegerField(read_only=True)
title = serializers.CharField()
content = serializers.CharField()
author = serializers.CharField()
使用:
python
serializer = ArticleSerializer(article, fields=('id', 'title'))
10.2 条件字段 #
python
class ArticleSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
title = serializers.CharField()
def get_fields(self):
fields = super().get_fields()
request = self.context.get('request')
if request and request.user.is_staff:
fields['internal_notes'] = serializers.CharField()
return fields
十一、总结 #
本章学习了序列化器的基础知识:
- 序列化器定义:理解序列化器的作用和功能
- 基本用法:序列化和反序列化数据
- 字段类型:掌握各种字段类型和参数
- 数据验证:实现数据验证逻辑
- 嵌套序列化:处理复杂的数据结构
序列化器是DRF的核心,让我们继续学习ModelSerializer来简化开发!
最后更新:2026-03-28