Django Rest Framework(DRF)序列化器简介(第1部分)
Source: Dev.to
什么是 Serializer?
在 DRF 中,serializer 就像是 桥梁,连接你的数据库和互联网。
- Django 模型将数据存储为 Python 对象。
- 当你想把这些数据发送给前端应用(如 React 或移动应用)时,不能直接发送 Python 对象。你需要使用大家都能理解的格式——通常是 JSON。
Serializers 执行三项主要工作:
- Serialization(序列化): 将复杂的 Python 对象(模型)转换为 Python 字典(便于渲染为 JSON)。
- Deserialization(反序列化): 将用户提交的 JSON 数据转换回复杂的 Python 对象。
- Validation(验证): 在将数据保存到数据库之前检查传入的数据是否正确。
为什么我们需要它们?
在标准的 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 中有多种序列化器,例如 ModelSerializer、HyperlinkedModelSerializer 和 ListSerializer。为了真正理解它们的工作原理,我们将从基础的 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。这样可以一步一步地看到数据的转换过程。
-
打开终端并运行 shell(确保已激活包含 Django 和 DRF 的虚拟环境):
python manage.py shell -
导入模型和序列化器:
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 模型。
但是你注意到有什么烦人的地方吗?
我们重复了很多代码。我们在模型中键入了 name、price 和 stock,随后又在序列化器中再次键入它们。在实际项目中,涉及数十个模型时,这违反了 DRY(Don’t Repeat Yourself,别重复自己)原则。
在 第 2 部分,我们将介绍 ModelSerializer,它是一个强大的快捷方式,能够自动为你编写所有这些样板代码。
