什么是序列化?
在我看来,序列化就是将复杂的对象数据转化为简单的通用数据格式(如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方法,若不实现报错如下:
下面我们简单实现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方法。