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