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))

序列化器的嵌套

posted @ 2023-01-04 20:29  Gazikel  阅读(100)  评论(0编辑  收藏  举报