Django-restframework 序列化器与反序列化器
序列化器
restframework中提供了所有可用的序列化器基类,引用方法如下:
from rest_framework import serializers
Serializer:序列化器基类,drf中所有的序列化器都必须继承于Serializer
ModelSerializer:模型序列化器基类,是序列化器基类的子类,在工作中,除了Serializer基类之外,最常用的序列化器基类。
转换字段声明
class StudentSerializer(serializers.Serializer):
""" 学生信息序列化器 """
# 1. 转换的字段声明
id = serializers.IntegerField()
name = serializers.CharField()
sex = serializers.BooleanField()
age = serializers.IntegerField()
description = serializers.CharField()
编写视图类
from django.http import JsonResponse
from django.views import View
from .serializers import StudentSerializer
from students.models import Student
class StudentView(View):
def get(self, request):
""" 序列化器,序列化阶段的调用 """
student_list = Student.objects.all()
# 1. 实例化序列化器,得到序列化对象
serializer = StudentSerializer(instance=student_list, many=True)
# 2. 调用序列化对象的data属性方法获取转换后的数据
data = serializer.data
# 3. 响应数据
return JsonResponse(data=data, status=200, safe=False, json_dumps_params={"ensure_ascii": False})
通过many=True,可以查询到多个模型对象。下面演示查询一个模型对象的例子:
from django.http import JsonResponse
from django.views import View
from .serializers import StudentSerializer
from students.models import Student
class StudentView(View):
def get(self, request):
""" 序列化器,序列化阶段的调用 """
student = Student.objects.first()
# 1. 实例化序列化器,得到序列化对象
serializer = StudentSerializer(instance=student, many=True)
# 2. 调用序列化对象的data属性方法获取转换后的数据
data = serializer.data
# 3. 响应数据
return JsonResponse(data=data, status=200, safe=False, json_dumps_params={"ensure_ascii": False})
如果序列化器的模型对象是多个,务必使用many=True
绑定路由
from .import views
from django.urls import path
urlpatterns = [
path("students", views.StudentView.as_view())
]
反序列化
使用序列化器进行反序列化时,需要对数据进行验证后,才能获取验证成功的数据或保存成模型类对象。
在获取反序列化的数据前,必须调用is_valid()方法进行验证,验证成功返回True,否则返回False。
验证失败,可以通过序列化器对象的errors属性获取错误信息,返回字典,包含了字段和字段的错误。如果是非字段错误,可以通过修改Rest Framework配置中的NON_FIELD_ERRORS_KEY来控制错误字典中的键名。
验证成功,可以通过序列化器对象的validated_data属性获取数据。
在定义序列化器时,指明每个字段的序列化类型和选项参数,本身就是一种验证行为。
转换字段声明
class StudentSerializer(serializers.Serializer):
""" 学生信息序列化器 """
# 1. 转换的字段声明
id = serializers.IntegerField(read_only=True) # 在客户端提交数据(反序列化阶段不会要求id字段)
name = serializers.CharField(required=True) # 反序列化阶段必填
sex = serializers.BooleanField(default=True) # 反序列化阶段,客户端没有提交,则默认为True
age = serializers.IntegerField(max_value=50, min_value=6, error_messages={
"min_value": "最小值不能低于1",
"max_value": "最大值不能大于50"
})
description = serializers.CharField(allow_null=True, allow_blank=True)
可以在这里面通过error_message
来定义验证错误时返回的信息。
编写视图类
class StudentView(View):
def get(self, request):
""" 反序列化-采用字段选项来验证数据"""
# 接收客户端提交的数据
# data = json.dumps(request.body)
# 模拟客户端的数据
data = {
"name": "xiaohong",
"age": 0,
"sex": True,
"classmate": 301,
"description": "这家伙很懒,什么都没留下!"
}
# 实例化序列化器,获取序列化对象
serializer = StudentSerializer(data=data)
# 调用序列化器进行数据验证
ret = serializer.is_valid()
# 获取验证以后的结果
if ret:
print(serializer.validated_data)
return JsonResponse(dict(serializer.validated_data))
else:
print(serializer.errors)
return JsonResponse(dict(serializer.errors))
下面是一种工作中更为常用的写法,即抛出异常:
class StudentView(View):
def get(self, request):
""" 反序列化-采用字段选项来验证数据"""
# 接收客户端提交的数据
# data = json.dumps(request.body)
# 模拟客户端的数据
data = {
"name": "xiaohong",
"age": 0,
"sex": True,
"classmate": 301,
"description": "这家伙很懒,什么都没留下!"
}
# 实例化序列化器,获取序列化对象
serializer = StudentSerializer(data=data)
# 调用序列化器进行数据验证
ret = serializer.is_valid(raise_exception=True)
# 获取验证以后的结果
return JsonResponse(dict(serializer.validated_data))
验证对象方法
自己编写对字段进行逻辑校验。
class StudentSerializer(serializers.Serializer):
""" 学生信息序列化器 """
# 1. 转换的字段声明
id = serializers.IntegerField(read_only=True) # 在客户端提交数据(反序列化阶段不会要求id字段)
name = serializers.CharField(required=True) # 反序列化阶段必填
sex = serializers.BooleanField(default=True) # 反序列化阶段,客户端没有提交,则默认为True
age = serializers.IntegerField(max_value=50, min_value=6, error_messages={
"min_value": "最小值不能低于1",
"max_value": "最大值不能大于50"
})
description = serializers.CharField(allow_null=True, allow_blank=True)
# 2. 如果当前序列化器继承的是ModelSerializer,则需要声明调用的模型信息
# 3. 验证代码的对象方法
def validate(self, attrs):
"""
验证来自客户端的所有数据
validate是固定方法名
attrs:是在序列化器实例化时data选项数据
"""
# 307班只能有女生,不能加入其他男生
if attrs['classmate'] == 307 and attrs['sex']:
raise serializers.ValidationError(detail='307班只能有小姐姐哦~', code='validate')
def validate_name(self, data):
""" 验证单个字段 """
print(data)
if data in ['python', 'django']:
# 在序列化器中验证失败,可以通过抛出异常的方式来告知
raise serializers.ValidationError(detail='学生姓名不能为python或django')
# 验证成功必须返回data数据
return data
模型操作方法
class StudentSerializer(serializers.Serializer):
""" 学生信息序列化器 """
# 1. 转换的字段声明
id = serializers.IntegerField(read_only=True) # 在客户端提交数据(反序列化阶段不会要求id字段)
name = serializers.CharField(required=True) # 反序列化阶段必填
sex = serializers.BooleanField(default=True) # 反序列化阶段,客户端没有提交,则默认为True
age = serializers.IntegerField(max_value=50, min_value=6, error_messages={
"min_value": "最小值不能低于1",
"max_value": "最大值不能大于50"
})
classmate = serializers.CharField(required=True)
description = serializers.CharField(allow_null=True, allow_blank=True)
# 4. 模型操作的方法
def create(self, validated_data):
""" 完成添加操作,添加数据以后,就自动实现了从字段变成对象的过程"""
return Student.objects.create(**validated_data)
def update(self, instance, validated_data):
""" 更新数据操作 """
instance.name = validated_data["name"]
instance.age = validated_data["age"]
instance.sex = validated_data["sex"]
instance.classmate = validated_data["classmate"]
instance.description = validated_data["description"]
instance.save()
return instance
在视图类中定义添加与修改的操作:
class StudentView(View):
def get(self, request):
pk = 5
try:
student = Student.objects.get(pk=pk)
except:
return JsonResponse({"errors": "未查询到此人"}, status=404)
# 模拟客户端的数据
data = {
"name": "xiaoming",
"age": 17,
"sex": True,
"classmate": "301",
"description": "这家伙很懒,什么都没留下!"
}
serializer = StudentSerializer(instance=student, data=data)
serializer.is_valid(raise_exception=True)
serializer.save()
return JsonResponse(serializer.data, status=201)
def get5(self, request):
# 模拟客户端的数据
data = {
"name": "xiaohong",
"age": 16,
"sex": True,
"classmate": "301",
"description": "这家伙很懒,什么都没留下!"
}
# 实例化序列化器,获取序列化对象
serializer = StudentSerializer(data=data)
# 调用序列化器进行数据验证
serializer.is_valid(raise_exception=True)
# 获取验证以后的结果,操作数据库
serializer.save()
return JsonResponse(dict(serializer.validated_data))