如何在 Django Python Web 框架中使用 Serializers

序列化将数据转换为可以存储或传输的格式,然后重建它以供使用。DRF 拥有最著名的 serializers。
83 位读者喜欢这篇文章。
Net catching 1s and 0s or data in the clouds

Opensource.com

序列化是将数据转换为可以存储或传输的格式,然后再重建它的过程。在开发应用程序或将数据存储在数据库、内存中或将其转换为文件时,它一直被使用。

最近,我在 Labcodes 帮助两位初级开发人员理解了 serializers,我认为与 Opensource.com 的读者分享我的方法会很好。

假设您正在为电子商务站点创建软件,并且您有一个 Order(订单)来记录某人以某个价格在某个日期购买单个产品的情况

class Order:
    def __init__(self, product, customer, price, date):
        self.product = product
        self.customer = customer
        self.price = price
        self.date = date

现在,假设您想从键值数据库中存储和检索订单数据。幸运的是,它的接口接受并返回字典,因此您需要将您的对象转换为字典

def serialize_order(order):
    return {
        'product': order.product,
        'customer': order.customer,
        'price': order.price,
        'date': order.date
    }

如果您想从该数据库中获取一些数据,您可以获取字典数据并将其转换为您的 Order 对象

def deserialize_order(order_data):
    return Order(
        product=order_data['product'],
        customer=order_data['customer'],
        price=order_data['price'],
        date=order_data['date'],
    )

对于简单数据来说,这非常简单,但是当您需要处理由复杂属性组成的复杂对象时,这种方法就无法很好地扩展。您还需要处理不同类型字段的验证,而这需要大量的手动工作。

这就是框架的 serializers 派上用场的地方。它们允许您创建带有少量样板代码的 serializers,这些 serializers 将适用于您的复杂情况。

Django 配备了一个序列化模块,允许您将 Models “翻译”成其他格式

from django.core import serializers

serializers.serialize('json', Order.objects.all())

它涵盖了 Web 应用程序最常用的情况,例如 JSON、YAML 和 XML。但是您也可以使用第三方 serializers 或创建自己的 serializers。您只需要在您的 settings.py 文件中注册它即可

# settings.py
SERIALIZATION_MODULES = {
    'my_format': appname.serializers.MyFormatSerializer,
}

要创建您自己的 MyFormatSerializer,您需要实现 .serialize() 方法并接受一个 queryset 和额外的 options 作为参数

class MyFormatSerializer:
    def serialize(self, queryset, **options):
        # serious serialization happening

现在您可以将您的 queryset 序列化为您的新格式

from django.core import serializers

serializers.serialize('my_format', Order.objects.all())

您可以使用 options 参数来定义您的 serializer 的行为。例如,如果您想定义在处理 ForeignKeys 时您将使用嵌套序列化,或者您只是希望数据返回其 primary keys,您可以传递一个 flat=True 参数作为 option 并在您的方法中处理它

class MyFormatSerializer:
    def serializer(self, queryset, **options):
        if options.get('flat', False):
            # don't recursively serialize relationships
        # recursively serialize relationships

使用 Django 序列化的一种方法是使用 loaddatadumpdata 管理命令。

DRF serializers

在 Django 社区中,Django REST framework (DRF) 提供了最著名的 serializers。虽然您可以使用 Django 的 serializers 来构建您将在您的 API 中响应的 JSON,但来自 REST framework 的 serializers 具有很好的功能,可以帮助您处理和轻松验证复杂数据。

在 Order 示例中,您可以创建一个像这样的 serializer

from restframework import serializers

class OrderSerializer(serializers.Serializer):
    product = serializers.CharField(max_length=255)
    customer = serializers.CharField(max_lenght=255)
    price = serializers.DecimalField(max_digits=5, decimal_places=2)
    date = serializers.DateField()

并轻松地序列化其数据

order = Order('pen', 'renato', 10.50, date.today())
serializer = OrderSerializer(order)

serializer.data
# {'product': 'pen', 'customer': 'renato', 'price': '10.50', 'date': '2020-08-16'}

为了能够从数据返回一个实例,您需要实现两个方法——create 和 update

from rest_framework import serializers

class OrderSerializer(serializers.Serializer):
    product = serializers.CharField(max_length=255)
    customer = serializers.CharField(max_length=255)
    price = serializers.DecimalField(max_digits=5, decimal_places=2)
    date = serializers.DateField()

    def create(self, validated_data):
        # perform order creation
        return order

    def update(self, instance, validated_data):
       # perform instance update
       return instance

之后,您可以通过调用 is_valid() 来验证数据,并调用 save() 来创建或更新实例,从而创建或更新实例

serializer = OrderSerializer(**data)
## to validate data, mandatory before calling save
serializer.is_valid() 
serializer.save()

Model serializers

在序列化数据时,您通常需要从数据库中进行,因此,从您的 models 中进行。ModelSerializer,就像 ModelForm 一样,提供了一个 API,用于从您的 models 创建 serializers。假设您有一个 Order model

from django.db import models


class Order(models.Model):
    product = models.CharField(max_length=255)
    customer = models.CharField(max_length=255)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    date = models.DateField()    

您可以像这样为其创建一个 serializer

from rest_framework import serializers


class OrderSerializer(serializers.ModelSerializer):
    class Meta:
        model = Order
        fields = '__all__'

Django 会自动在 serializer 中包含所有 model fields,并创建 createupdate 方法。

在基于类的视图 (CBVs) 中使用 serializers

就像 Django 的 CBVs 中的 Forms 一样,serializers 与 DRF 很好地集成。您可以设置 serializer_class 属性,以便 serializer 可用于视图

from rest_framework import generics


class OrderListCreateAPIView(generics.ListCreateAPIView):
    queryset = Order.objects.all()
    serializer_class = OrderSerializer

您还可以定义 get_serializer_class() 方法

from rest_framework import generics


class OrderListCreateAPIView(generics.ListCreateAPIView):
    queryset = Order.objects.all()
    
    def get_serializer_class(self):
        if is_free_order():
            return FreeOrderSerializer
        return OrderSerializer

CBVs 中还有其他与 serializers 交互的方法。例如,get_serializer() 返回一个已经实例化的 serializer,而 get_serializer_context() 返回您在创建 serializer 实例时将传递给 serializer 的参数。对于创建或更新数据的视图,有 createupdate 来使用 is_valid 方法验证要保存的数据,以及 perform_createperform_update 来调用 serializer 的 save 方法。

了解更多

有关其他资源,请参阅我的朋友 André Ericson 的 Classy Django REST Framework 网站。它是一个 Classy Class-Based Views REST Framework 版本,可让您深入检查构成 DRF 的类。当然,官方文档也是一个很棒的资源。

接下来阅读什么
标签
Photo of renato with Python's logo in top right
Labcodes (https://labcodes.com.br) 的联合创始人,以及位于巴西的软件工程师。在巴西组织了许多会议,包括 2014 年的 Python Brazil (Brazilian PyCon)。自 2011 年以来,我一直从事 Python 和 Django 的工作。

评论已关闭。

© . All rights reserved.