rest_framework学习之序列化(Serializer)

什么是序列化?

在我看来,序列化就是将复杂的对象数据转化为简单的通用数据格式(如json),这么一个过程就是序列化。反序列化同理。

我们看下DRF对序列化解释,序列化器允许将复杂数据(如查询集和模型实例)转换为原生Python数据类型,然后可以轻松地将其呈现为JSON、XML或其他内容类型。序列化器还提供反序列化,允许在首先验证传入的数据之后将解析后的数据转换回复杂类型。

PS:还是官方专业~~~

当我们用ORM查询出数据集时,默认存放在Django的QuerySet对象中,我们不能直接把QuerySet对象的数据返回给前端,在给前端前我们需要对数据进行解析,若我们自己实现,肯定是遍历、创建字典、把数据存到字典内、然后在json dump等,做这一系列冗余无聊的动作

但当我们使用Serializer后,代码相比较来说就会很简洁,也更安全。

序列化

使用前我们先看下我定义的Model,如下:

from django.db import models


class ComModel(models.Model):
    """
    class com
    """
    email = models.EmailField()
    content = models.CharField(max_length=200)
    created = models.DateTimeField()
    port = models.IntegerField()

我们为该Model做序列化如下:

from rest_framework import serializers


class ComSerializer(serializers.Serializer):
    email = serializers.EmailField()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()
    port = serializers.IntegerField()

设置好序列化后,视图层代码如下:

from rest_framework.views import APIView
from core.models import ComModel
from core.api.serializers import ComSerializer

class TestView(APIView):

    def get(self, request):
        queryset = ComModel.objects.all()
        serializer = ComSerializer(queryset, many=True)
        return Response(serializer.data)

至此,序列化完成,前端可正常展示数据。

我们发现个问题,若所有的Model都按上述做序列化,我们得要定义两遍字段类型,Model里面一次,Serializer里面一次,显得较为麻烦,下面我们使用更简单的ModelSerializer,修改序列化类如下:

from rest_framework import serializers
from core.models import ComModel


class ComSerializer(serializers.ModelSerializer):

    class Meta:
        model = ComModel
        fields = '__all__'

只需如上定义也可完成序列化,方便了许多。

反序列化

上面我们演示了查询时将对象序列化为json,下面我们将演示把POST/PUT的数据反序列化插入或更新到数据库。当我们需要创建或更新数据时,必须要在Serializer类中实现create、update方法,若不实现报错如下:

rest_framework学习之序列化(Serializer)_第1张图片

下面我们简单实现create和update方法,代码如下:

serializers.py

from rest_framework import serializers
from core.models import ComModel


class ComSerializer(serializers.Serializer):
    email = serializers.EmailField()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()
    port = serializers.IntegerField()

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

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

views.py

class TestView(APIView):

    def get(self, request):
        queryset = ComModel.objects.all()
        serializer = ComSerializer(queryset, many=True)
        return Response(serializer.data)

    def post(self, request):
        data = request.data
        serializer = ComSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors)

    def put(self, request):
        data = request.data
        obj_id = data.pop('id')
        instance = ComModel.objects.get(id=obj_id)
        print("======================", instance.content)
        serializer = ComSerializer(instance, data=data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors)

这里有几个需要注意的:

1、如需要保存数据至数据库,需要在serializers.py中的update方法内调用instance.save()使数据先保存至instance实例中,其次需要在views.py中的put方法内调用serializer.save()保存至序列化对象内并落库;

2、serializer = ComSerializer(instance, data=data, partial=True),其中partial参数设置为True,表示可以更新部分数据,否则不能正常更新。

 

我们利用上述的ModelSerializer,ModelSerializer默认为我们实现create、update方法,我们无需重复实现,serializer代码如下:

serializers.py

from rest_framework import serializers
from core.models import ComModel


class ComSerializer(serializers.ModelSerializer):

    class Meta:
        model = ComModel
        fields = '__all__'

这样就会很方便了,但当实际开发时肯定有些定制化需求,到时候重写create或update方法即可。

 

这里我们要强调一下,我们用的是ModelSerializer类,这个类内部实现了create、update方法,这两个方法是创建、更新数据时调用的方法,但Serializer类默认是没有create和update方法的,所以就不能创建或更新数据,如需要创建更新那就必须在序列化类中实现create、update方法。

 

 

你可能感兴趣的:(django)