DRF: Serializer的使用方式

serializers.Serializer 是 Django Rest Framework (DRF) 中用于数据序列化和反序列化的核心类之一。它允许你将复杂的数据类型(如 Django 模型实例、查询集或字典)转换为 Python 原生数据类型(如字典、列表等),以及将这些数据类型从 Python 原生格式反向转换回模型实例。

1. 基本概念

  • 序列化(Serialization):将 Python 数据类型(如模型实例、查询集等)转换为 JSON 或其他格式(例如 XML)。
  • 反序列化(Deserialization):将传入的 JSON(或其他格式)数据转换为 Python 数据类型(例如模型实例、字典等)。

2. 使用 serializers.Serializer

serializers.Serializer 主要通过定义字段来序列化数据,并在反序列化时验证数据的有效性。你可以使用不同的字段类型(例如 CharFieldIntegerFieldEmailField 等)来指定数据的格式和类型。

基本的 serializers.Serializer 使用步骤:

  1. 定义序列化器类:继承 serializers.Serializer 并定义字段。
  2. 创建序列化器实例:通过实例化序列化器,传入数据进行序列化。
  3. 验证数据:通过 is_valid() 方法验证反序列化的数据是否合法。
  4. 访问序列化后的数据:通过 data 属性访问序列化后的数据。

示例 1:简单的序列化器

from rest_framework import serializers

# 定义一个简单的序列化器
class UserSerializer(serializers.Serializer):
    username = serializers.CharField(max_length=100)
    email = serializers.EmailField()

# 创建一个数据字典
data = {'username': 'john_doe', 'email': 'john@example.com'}

# 实例化序列化器并传入数据
serializer = UserSerializer(data=data)

# 验证数据是否合法
if serializer.is_valid():
    # 输出序列化后的数据
    print(serializer.data)
else:
    print(serializer.errors)

输出:

{'username': 'john_doe', 'email': 'john@example.com'}

示例 2:反序列化并验证数据

在反序列化时,is_valid() 会自动验证字段数据的合法性,如果数据无效,你可以通过 errors 属性查看详细的错误信息。

data = {'username': 'john_doe', 'email': 'invalid_email'}

serializer = UserSerializer(data=data)

if serializer.is_valid():
    print("Valid data:", serializer.validated_data)
else:
    print("Errors:", serializer.errors)

输出:

Errors: {'email': ['Enter a valid email address.']}

3. serializers.Serializer 常用字段类型

在定义序列化器时,你可以使用 DRF 提供的字段类型来控制数据的格式和验证规则。常用的字段类型有:

  • CharField:用于序列化字符串数据。
  • IntegerField:用于序列化整数数据。
  • EmailField:用于序列化邮箱地址。
  • BooleanField:用于序列化布尔值。
  • DateTimeField:用于序列化日期时间。
  • DecimalField:用于序列化浮动数据(例如货币值)。

示例 3:使用不同字段类型

class ProductSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=200)
    price = serializers.DecimalField(max_digits=10, decimal_places=2)
    available = serializers.BooleanField(default=True)

data = {
    'name': 'Laptop',
    'price': '1200.50',  # 字符串形式的数字,DRF 会将其转换为 Decimal
    'available': True
}

serializer = ProductSerializer(data=data)

if serializer.is_valid():
    print("Serialized Data:", serializer.data)
else:
    print("Errors:", serializer.errors)

输出:

Serialized Data: {'name': 'Laptop', 'price': '1200.50', 'available': True}

4. validated_data 属性

当数据通过 is_valid() 方法验证成功后,validated_data 属性会包含有效的、经过验证的字段数据。它是一个标准的 Python 字典,包含你想要序列化的字段。

serializer = UserSerializer(data={'username': 'john_doe', 'email': 'john@example.com'})

if serializer.is_valid():
    # 获取经过验证的字段数据
    validated_data = serializer.validated_data
    print(validated_data)

输出:

{'username': 'john_doe', 'email': 'john@example.com'}

5. 嵌套序列化器

serializers.Serializer 支持嵌套序列化器。你可以在一个序列化器中嵌入另一个序列化器,用于序列化更复杂的结构。

示例 4:嵌套序列化器

class AddressSerializer(serializers.Serializer):
    street = serializers.CharField(max_length=100)
    city = serializers.CharField(max_length=100)

class UserSerializer(serializers.Serializer):
    username = serializers.CharField(max_length=100)
    email = serializers.EmailField()
    address = AddressSerializer()

data = {
    'username': 'john_doe',
    'email': 'john@example.com',
    'address': {'street': '123 Main St', 'city': 'New York'}
}

serializer = UserSerializer(data=data)

if serializer.is_valid():
    print(serializer.data)

输出:

{
    'username': 'john_doe',
    'email': 'john@example.com',
    'address': {
        'street': '123 Main St',
        'city': 'New York'
    }
}

6. create() 和 update() 方法

当你想要反序列化并创建或更新数据库中的对象时,你可以在序列化器中重写 create()update() 方法。

示例 5:重写 create()update() 方法

class UserSerializer(serializers.Serializer):
    username = serializers.CharField(max_length=100)
    email = serializers.EmailField()

    def create(self, validated_data):
        return User.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.username = validated_data.get('username', instance.username)
        instance.email = validated_data.get('email', instance.email)
        instance.save()
        return instance

在上面的示例中,create() 方法用于根据验证的数据创建一个新的 User 对象,而 update() 方法则更新现有的 User 对象。

7. to_representation() 和 to_internal_value()

  • to_representation():用于将序列化器数据转换为 Python 原生数据类型(例如字典)。
  • to_internal_value():用于将传入的原始数据(通常是 JSON)转换为内部 Python 数据类型。

你可以重写这两个方法以实现自定义的序列化和反序列化行为。

总结

  • serializers.Serializer 是 DRF 中非常强大的类,用于实现数据序列化和反序列化。
  • 它允许你定义数据的字段、进行验证、嵌套其他序列化器,以及创建或更新数据库模型实例。
  • 常见的字段类型包括 CharField、IntegerField、EmailField 等。
  • 你可以根据需求使用 create() 和 update() 方法来创建或更新对象。


文章标签:

评论(0)