Django Rest Framework(DRF)序列化器简介(第1部分)

发布: (2026年2月3日 GMT+8 15:48)
8 min read
原文: Dev.to

Source: Dev.to

什么是 Serializer?

在 DRF 中,serializer 就像是 桥梁,连接你的数据库和互联网。

  • Django 模型将数据存储为 Python 对象。
  • 当你想把这些数据发送给前端应用(如 React 或移动应用)时,不能直接发送 Python 对象。你需要使用大家都能理解的格式——通常是 JSON

Serializers 执行三项主要工作:

  1. Serialization(序列化): 将复杂的 Python 对象(模型)转换为 Python 字典(便于渲染为 JSON)。
  2. Deserialization(反序列化): 将用户提交的 JSON 数据转换回复杂的 Python 对象。
  3. Validation(验证): 在将数据保存到数据库之前检查传入的数据是否正确。

Serialization and Deserialization

为什么我们需要它们?

在标准的 Django 应用中,我们使用模型(Models)与数据交互。让我们看一个简单的场景。我们想要构建一个商店,于是定义一个 ProductModel

(在你的 models.py 文件中创建此模型)

from django.db import models

class ProductModel(models.Model):
    name = models.CharField(max_length=150)
    description = models.TextField()
    price = models.DecimalField(max_digits=10, decimal_places=2)
    stock = models.IntegerField()
    is_active = models.BooleanField(default=True)

    def __str__(self):
        return self.name

如果你尝试直接将 ProductModel 实例发送到网页浏览器,它会崩溃。浏览器不懂 “Python 类”,它只懂 “JSON”。

我们需要一个翻译器。这个翻译器就是 Serializer

创建您的第一个序列化器

DRF 中有多种序列化器,例如 ModelSerializerHyperlinkedModelSerializerListSerializer。为了真正理解它们的工作原理,我们将从基础的 Serializer 类开始。

在你的应用(我们称之为 demo)中创建一个 serializers.py 文件,并定义一个与模型对应的序列化器:

# demo/serializers.py
from rest_framework import serializers 

class ProductSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=150)
    description = serializers.CharField()
    price = serializers.DecimalField(max_digits=10, decimal_places=2)
    stock = serializers.IntegerField()
    is_active = serializers.BooleanField()

注意: 我们必须重复模型中的字段。我们将在第 2 部分解决这种冗余,但目前,这种显式的写法有助于我们准确了解发生了什么。

观察序列化的实际效果

学习 DRF 的最佳方式不是通过网页浏览器,而是通过 Python Shell。这样可以一步一步地看到数据的转换过程。

  1. 打开终端并运行 shell(确保已激活包含 Django 和 DRF 的虚拟环境):

    python manage.py shell
  2. 导入模型和序列化器:

    from demo.models import ProductModel
    from demo.serializers import ProductSerializer

步骤 1:创建示例数据

使用标准的 Django 代码在数据库中创建一个商品:

product = ProductModel.objects.create(
    name='Logitech MX Master',
    description='Ergonomic Logitech Mouse',
    price=110.99,
    stock=72,
    is_active=True
)

步骤 2:序列化数据

将商品对象传入我们的序列化器:

serializer = ProductSerializer(product)

要查看转换后的数据,访问 .data 属性:

print(serializer.data)

输出:

{
   "name": "Logitech MX Master",
   "description": "Ergonomic Logitech Mouse",
   "price": "110.99",
   "stock": 72,
   "is_active": true
}

成功!序列化器将 Python 对象转换成了 Python 字典。这个字典现在可以轻松地转为 JSON 并通过 API 发送。

反序列化(逆向过程)

现在,我们来看一下相反的情况。用户想通过你的 API 创建一个新产品。他们会向你发送一个 JSON 对象。

假设这是传入的数据:

data = {
    "name": "Mechanical Keyboard",
    "description": "Backlit mechanical keyboard",
    "price": "24.99",
    "stock": 10,
    "is_active": True
}

使用 data 参数将原始数据传递给序列化器:

serializer = ProductSerializer(data=data)

常见错误: 在验证之前尝试访问 .data

# 不要这么做
print(serializer.data)

你会得到一个错误:

AssertionError: When a serializer is passed a `data` keyword argument you must call `.is_valid()` before accessing `.data`.

正确的反序列化流程

if serializer.is_valid():
    product_instance = serializer.save()   # 创建一个 ProductModel 实例
    print("Created:", product_instance)
else:
    print("Validation errors:", serializer.errors)
  • serializer.is_valid() 会运行验证逻辑。
  • 如果数据通过验证,serializer.save() 会创建(或更新)模型实例。
  • 如果验证失败,serializer.errors 包含错误信息的字典。

小结

  • 序列化器 在 Django 模型(Python 对象)和 JSON 兼容数据之间进行转换。
  • 它们处理 序列化反序列化验证
  • 从基础的 Serializer 类开始,你可以清晰地看到每一步;随后你会看到 ModelSerializer 如何消除冗余。

访问序列化的 .data 表示

# Example usage in the Django shell
serializer = ProductSerializer(data=product_data)
if serializer.is_valid():
    print(serializer.validated_data)
else:
    print(serializer.errors)

DRF 保护你的数据库。它拒绝在你确认数据有效之前让你操作数据。你 必须 首先调用 is_valid()。如果没有调用 is_valid() 方法,Python 将抛出 AssertionError

由于我们的数据符合要求(例如,price 是小数,stock 是整数,is_active 是布尔值),is_valid() 返回 True

Source:

保存数据

现在数据已经有效,我们想把它保存到数据库中。通常,你会调用 serializer.save()

但是,如果你现在尝试运行 serializer.save()它会失败

为什么? 因为基类 Serializer 并不知道 如何 创建 ProductModel。我们必须告诉它该怎么做。

实现 create() 方法

编辑 serializers.py 并添加一个 create() 方法:

class ProductSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=150)
    description = serializers.CharField()
    price = serializers.DecimalField(max_digits=10, decimal_places=2)
    stock = serializers.IntegerField()
    is_active = serializers.BooleanField()

    # We must implement this to support saving data
    def create(self, validated_data):
        # Unpack the validated data and create a model instance
        return ProductModel.objects.create(**validated_data)

现在,回到你的 shell,运行:

serializer.save()

它将成功在你的数据库中创建 “Mechanical Keyboard”

总结

我们已经成功构建了一个序列化器,它可以:

  • 读取 Django 模型并将其转换为字典。
  • 写入:接受一个字典,进行验证,并将其转换为 Django 模型。

但是你注意到有什么烦人的地方吗?
我们重复了很多代码。我们在模型中键入了 namepricestock,随后又在序列化器中再次键入它们。在实际项目中,涉及数十个模型时,这违反了 DRY(Don’t Repeat Yourself,别重复自己)原则。

第 2 部分,我们将介绍 ModelSerializer,它是一个强大的快捷方式,能够自动为你编写所有这些样板代码。

参考文献

Back to Blog

相关文章

阅读更多 »

歌词搜索者的音乐

概述 本应用允许用户通过提供乐队/艺术家名称和歌曲标题来搜索歌词。图形界面使用 St... 构建。

学习 Python:实战

TL;DR 我没想到 Python 会既让人痛苦又让人欣喜。我的学习之旅 我已经学习 Python 三个月了,期间经历了……