Django 序列化详解:从 Model 到 JSON,全面掌握数据转换机制

一、引言:什么是 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 Book

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__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 = Book
        fields = ['id', 'title', 'title_upper', 'author', 'published']

    def get_title_upper(self, obj):
        return obj.title.upper()

2. 添加验证逻辑

复制代码
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ['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 = Author
        fields = ['id', 'name']

class BookSerializer(serializers.ModelSerializer):
    author = AuthorSerializer()

    class Meta:
        model = Book
        fields = ['id', 'title', 'author', 'published']

2. 反向关系(Related Field)

复制代码
class AuthorSerializer(serializers.ModelSerializer):
    books = BookSerializer(many=True, read_only=True)

    class Meta:
        model = Author
        fields = ['id', 'name', 'books']

3. 可写嵌套关系

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

复制代码
class BookSerializer(serializers.ModelSerializer):
    author = AuthorSerializer()

    class Meta:
        model = Book
        fields = ['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 = Book
        fields = '__all__'
        depth = 1  # 自动展开外键关系(不推荐用于复杂结构)

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

复制代码
from django.core.cache import cache

def 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 = Book
        fields = ['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() 方法 |
| 嵌套结构 | 使用 SerializerMethodFieldPrefetch |
| 安全性 | 使用 read_only_fieldsextra_kwargs 控制字段权限 |
| 代码复用 | 抽取公共字段、继承 ModelSerializer 实现复用 |


十、总结

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

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

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