【Django学习】(八)使用序列化器进行序列化与反序列化操作

简介: 【Django学习】(八)使用序列化器进行序列化与反序列化操作

之前我们使用的是djang的views视图集里自定义序列化输出与反序列化输入,弊端也显而易见,代码比较冗余繁琐,最主要的是 数据校验,非常复杂,比如是否传递数据、是否传递json格式的参数、是否传递合法的参数(参数类型、参数的个数、参数的其他约束),所以接下来要学习使用序列化器进行序列化与反序列化操作。

定义序列化器文件serializers.py

  • 定义序列化器类,需要继承Serializer基类或者Serializer的子类
  • 定义的序列化器类中的字段名要与模型类中的字段名保持一次
  • label和help_text与模型类中的verbose_name和help_text是一致的
  • 默认情况下,序列化类中定义了哪些字段,那么哪些字段就会被返回,如果不想返回给前端,那么就直接不定义
  • 默认情况下,序列化类中定义了哪些字段,那么哪些字段就一定要输入
  • 如果某个字段,指定了read_only=True,那么该字段,只进行序列化输出,不需要输入(反序列化输入)
  • 如果某个字段,指定了write_only=True,那么该字段,只进行反序列化输入,不需要输出(序列化输出)
  • 设置validators参数,可以为该字段指定约束条件
  • validators参数只能为列表或者元组
  • 可以使用UniqueValidator来指定唯一约束条件,第一个参数为查询集对象,message关键字参数可以指定具体的报错信息,列表或者元组中的每一个元素,为一个约束条件
  • 一个是不传该字段,一个是传空值(空字符串),是不一样的
  • allow_blank=True,那么该字段可以传递空字符串“”
  • allow_null=True,那么该字段可以传递空值(null)
  • 如果设置default参数,那么前端可以不传该字段,会自动使用默认值来传递,同时不会校验
class ProjectSerializer(serializers.Serializer):
    id = serializers.IntegerField(label="id主键", help_text="id主键", read_only=True)
    name = serializers.CharField(label="接口名称", help_text="接口名称", max_length=10, min_length=5,
                                 validators=[UniqueValidator(ProjectsModel.objects.all(), message="项目名称不可重复!")])
    leader = serializers.CharField(label="负责人", help_text="负责人")
    tester = serializers.CharField(label="接口测试人员", help_text="接口测试人员", max_length=10, min_length=5,
                                   error_messages={"min_length": "tester长度不能少于5位", "max_length": "tester长度不能大于10位",
                                                   "required": "tester字段为必填项"})
    desc = serializers.CharField(label="接口描述", help_text="接口描述", allow_null=True, default=" desc默认值")
    publish_app = serializers.CharField(label="开发应用", help_text="开发应用", allow_null=True, default=" publish_app默认值")
    programmer = serializers.CharField(label="开发人员", help_text="开发人员", allow_null=True, default=" programmer默认值")

改造之前写的views.py文件

class ProjectsDetailViews(View):
    def get_object(self, pk):
        # 查询指定pk的数据
        ret = {
            "msg": "传参异常",
            "code": 404
        }
        try:
            return ProjectsModel.objects.get(pk=pk)
        # 如果入参是不存在的id数据,抛出异常
        except Exception:
            return JsonResponse(ret, json_dumps_params={"ensure_ascii": False}, status=404)
    def get(self, request, pk):
        pro=self.get_object(pk)
        serializer_obj=ProjectSerializer(instance=pro)
        return JsonResponse(serializer_obj.data,json_dumps_params={"ensure_ascii": False})
    # 更新数据
    def put(self, request, pk):
        ret = {
            "msg": "传参异常",
            "code": 404
        }
        try:
            # 查出对应id的数据
            query_data = self.get_object(pk)
            # 提取传入的参数
            data_str = request.body.decode('utf-8')
            data_dict = json.loads(data_str)
        except Exception:
            return JsonResponse(ret, json_dumps_params={"ensure_ascii": False})
        serializer_obj = ProjectSerializer(data=data_dict)
        if not serializer_obj.is_valid():
            ret.update(serializer_obj.errors)
            return JsonResponse(ret, json_dumps_params={"ensure_ascii": False})
        # 修改老数据,传入新数据给对应字段
        query_data.name = serializer_obj.validated_data.get("name")
        query_data.leader = serializer_obj.validated_data.get("leader")
        query_data.desc = serializer_obj.validated_data.get("desc")
        query_data.programmer = serializer_obj.validated_data.get("programmer")
        query_data.tester = serializer_obj.validated_data.get("tester")
        query_data.publish_app = serializer_obj.validated_data.get("publish_app")
        # 保存更新的数据
        query_data.save()
        # 序列化输出,展示数据
        serializer_obj1 = ProjectSerializer(instance=pro)
        return JsonResponse(serializer_obj1.data, json_dumps_params={"ensure_ascii": False})
    # 删除数据
    def delete(self, request, pk):
        ret = {
            "msg": "删除成功!"
        }
        ret_error = {
            "msg": "传参异常",
            "code": 404
        }
        try:
            # 根据id查出对应数据
            query_data = ProjectsModel.objects.get(pk=pk)
            # 删除指定数据
            query_data.delete()
            # 一般删除数据的输出为None
        except Exception:
            return JsonResponse(ret_error, json_dumps_params={"ensure_ascii": False}, status=200)
        return JsonResponse(ret, json_dumps_params={"ensure_ascii": False}, status=200)
class ProjectsViews(View):
    # 查询全部数据
    def get(self, request):
        pro_data = ProjectsModel.objects.all()
        serializer_obj=ProjectSerializer(instance=pro_data,many=True)
        return JsonResponse(serializer_obj.data, safe=False, json_dumps_params={"ensure_ascii": False}, status=200)
    # 创建数据
    def post(self, request):
        ret = {
            "msg": "传参异常",
            "code": 404
        }
        try:
            json_str = request.body.decode('utf-8')
            data_dict = json.loads(json_str)
        # 如果入参不是json格式数据,抛出异常
        except json.JSONDecodeError:
            return JsonResponse(ret, json_dumps_params={"ensure_ascii": False}, status=404)
        # 反序列化输入
        serializer_obj = ProjectSerializer(data=data_dict)
        if not serializer_obj.is_valid(raise_exception=True):
            ret.update(serializer_obj.errors)
            return JsonResponse(ret, json_dumps_params={"ensure_ascii": False}, status=404)
        create_data = ProjectsModel.objects.create(**serializer_obj.validated_data)
        #序列化输出
        serializer_obj1=ProjectSerializer(instance=create_data)
        return JsonResponse(serializer_obj1.data, json_dumps_params={"ensure_ascii": False}, status=200)

序列化输出:

  • 将模型类对象传递给instance,会返回一个序列化器类对象
  • 可以使用序列化器对象的data属性,获取序列化之后的数据(字典或者嵌套字典的列表)
  • 如果传递的是查询集对象,那么需要添加many=True

反序列化输入:

  • 将字典类型或者(嵌套字典的列表)传递给data参数,会返回一个序列化器类对象
  • 必须先调用序列化器类对象.is_valid()方法,才会开始校验参数,检验成功会返回True,否则返回False
  • 可以使用序列化器类对象.errors属性,获取报错信息(字典类型)
  • 可以使用序列化器类对象.validated_data属性,获取校验通过之后的数据
  • is_valid()方法,可以设置raise_exception=True,那么校验不通过,会抛出异常

相关文章
|
3月前
|
XML 存储 JSON
Twaver-HTML5基础学习(19)数据容器(2)_数据序列化_XML、Json
本文介绍了Twaver HTML5中的数据序列化,包括XML和JSON格式的序列化与反序列化方法。文章通过示例代码展示了如何将DataBox中的数据序列化为XML和JSON字符串,以及如何从这些字符串中反序列化数据,重建DataBox中的对象。此外,还提到了用户自定义属性的序列化注册方法。
48 1
|
2月前
|
IDE 关系型数据库 MySQL
Django学习一:创建Django框架,介绍Django的项目结构和开发逻辑。创建应用,编写主包和应用中的helloworld
这篇文章是关于如何创建一个Django框架,介绍Django的项目结构和开发逻辑,并指导如何创建应用和编写“Hello, World!”程序的教程。
55 3
Django学习一:创建Django框架,介绍Django的项目结构和开发逻辑。创建应用,编写主包和应用中的helloworld
|
29天前
|
JSON 数据格式 索引
Python中序列化/反序列化JSON格式的数据
【11月更文挑战第4天】本文介绍了 Python 中使用 `json` 模块进行序列化和反序列化的操作。序列化是指将 Python 对象(如字典、列表)转换为 JSON 字符串,主要使用 `json.dumps` 方法。示例包括基本的字典和列表序列化,以及自定义类的序列化。反序列化则是将 JSON 字符串转换回 Python 对象,使用 `json.loads` 方法。文中还提供了具体的代码示例,展示了如何处理不同类型的 Python 对象。
|
1月前
|
存储 安全 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第22天】在Java的世界里,对象序列化和反序列化是数据持久化和网络传输的关键技术。本文将带你了解如何在Java中实现对象的序列化与反序列化,并探讨其背后的原理。通过实际代码示例,我们将一步步展示如何将复杂数据结构转换为字节流,以及如何将这些字节流还原为Java对象。文章还将讨论在使用序列化时应注意的安全性问题,以确保你的应用程序既高效又安全。
|
2月前
|
存储 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第9天】在Java的世界里,对象序列化是连接数据持久化与网络通信的桥梁。本文将深入探讨Java对象序列化的机制、实践方法及反序列化过程,通过代码示例揭示其背后的原理。从基础概念到高级应用,我们将一步步揭开序列化技术的神秘面纱,让读者能够掌握这一强大工具,以应对数据存储和传输的挑战。
|
2月前
|
SQL Java 数据库
Django学习三:views业务层中通过models对实体对象进行的增、删、改、查操作。
这篇文章是关于如何使用Django框架的ORM系统在视图(views)层面进行数据库的增、删、改、查操作的教程。
23 0
Django学习三:views业务层中通过models对实体对象进行的增、删、改、查操作。
|
2月前
|
关系型数据库 MySQL Java
Django学习二:配置mysql,创建model实例,自动创建数据库表,对mysql数据库表已经创建好的进行直接操作和实验。
这篇文章是关于如何使用Django框架配置MySQL数据库,创建模型实例,并自动或手动创建数据库表,以及对这些表进行操作的详细教程。
78 0
Django学习二:配置mysql,创建model实例,自动创建数据库表,对mysql数据库表已经创建好的进行直接操作和实验。
|
2月前
|
存储 安全 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第3天】在Java编程的世界里,对象序列化与反序列化是实现数据持久化和网络传输的关键技术。本文将深入探讨Java序列化的原理、应用场景以及如何通过代码示例实现对象的序列化与反序列化过程。从基础概念到实践操作,我们将一步步揭示这一技术的魅力所在。
|
1月前
|
存储 缓存 NoSQL
一篇搞懂!Java对象序列化与反序列化的底层逻辑
本文介绍了Java中的序列化与反序列化,包括基本概念、应用场景、实现方式及注意事项。序列化是将对象转换为字节流,便于存储和传输;反序列化则是将字节流还原为对象。文中详细讲解了实现序列化的步骤,以及常见的反序列化失败原因和最佳实践。通过实例和代码示例,帮助读者更好地理解和应用这一重要技术。
33 0
|
3月前
|
JSON 安全 编译器
扩展类实例的序列化和反序列化
扩展类实例的序列化和反序列化
38 1