rest_framework(3)序列化和反序列化(一)

这篇具有很好参考价值的文章主要介绍了rest_framework(3)序列化和反序列化(一)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本系列文章中的上一篇文章:rest_framework.views.APIView 源码解析

urls.py 文件

from django.urls import path
from sers.views import BookView
urlpatterns = [
    path('sers/book/', BookView.as_view()),
}

models.py 文件

from django.db import models


# Create your models here.
class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name="书籍名称")
    price = models.IntegerField(verbose_name="价格")
    pub_date = models.DateField(verbose_name="出版日期")

view.py 文件

导入的包

from rest_framework.views import APIView
from rest_framework import serializers
from rest_framework.response import Response
from sers.models import Book

序列化器定义

# 2、定义序列化器
# 一个序列化类是针对某个模型(数据库表)进行设计的
class BookSerializer(serializers.Serializer):
    # 这些字段对应着数据库表的字段和类型
    # CharField、IntegerField、DateField 在反序列化的时候校验数据用的
    # 比如 title 要求是字符串,且长度要求不超过 32 位
    title = serializers.CharField(max_length=32)
    price = serializers.IntegerField()
    # pub_date = serializers.DateField()
    # 如果想序列化后的键的名字自定义
    # 则要指定 source="pub_date" 参数,对应数据库里的字段名
    date = serializers.DateField(source="pub_date")

    # 重写父类中的 create 方法,实现自己的数据保存逻辑
    # create 方法需要返回值,因为在源码中 save 方法需要接收 create 方法的返回值
    def create(self, validated_data):
        new_book = Book.objects.create(**self.validated_data)
        return new_book

BookView 类

get 方法中是序列化的使用,post 方法中是反序列化的使用

class BookView(APIView):
    # 假设有一个 get 请求,查询所有书籍信息
    def get(self, request):
        # 1、获取所有的书籍对象,返回一个 QuerySet 集合
        book_list = Book.objects.all()

        # 3、构建序列化器对象
        # instance=book_list 表示将 book_list 进行序列化
        # many=True 因为要序列化的是一个集合,所以有多个序列化对象, 所以 many=True
        # data=book_list 则表示将 book_list 进行反序列化
        _serializers = BookSerializer(instance=book_list, many=True)

        # 将序列化的结果返回给客户端
        # serializers.data 存放着序列化的结果
        # HttpResponse 将序列化后的结果按照自己的处理逻辑进行解析,然后发回给客户端
        # 但是前端拿到的结果还是有一些不便于阅读
        # return HttpResponse(_serializers.data)

        """
        _serializers.data 时发生以下动作:
            temp = []
            for obj in book_list:
                t = {}
                # BookSerializer 类中有几个字段,字典 t 中就会有几个键值对
                # BookSerializer 类中的字段名要和数据库表字段一样
                # 否则 obj.title 获取值的时候就会出错
                t["title"] = obj.title
                t["price"] = obj.price
                # 除非自定义了名字:date = serializers.DateField(source="pub_date")
                # t["pub_date"] = obj.pub_date
                t["date"] = obj.date
                
                temp.append(t)
            return temp
        """

        # 而利用 rest_framework.response 中的 Response 对序列化的结果进行处理
        # 将会得到一个真正的 Content-Type 为 json 的 json 格式的数据
        return Response(_serializers.data)

    # 假设有一个 post 请求,添加一个书籍
    def post(self, request):
        # 获取前端传过来的要添加的书籍信息
        # 因为继承了 APIView ,request 在 dispatch 中被重新构建了
        # 所以获取 post 请求的数据通过 request.date 得到
        # 得到的数据格式为 json 格式
        # book = request.date

        # 构建序列化器对象
        serializer = BookSerializer(data=request.date)
        # 校验数据
        """
        is_valid() 方法的执行过程:
            遍历所有的字段,看是否满足序列化器中定义的要求
            (如 title 是否是字符串,长度是否超过32位)
            通过校验的字段和其值放在字典 serializer.validated_date 中
            没有通过的字段放在字典 serializer.errors 中,其中键为字段名,值为错误原因
            如果所有字段都通过,is_valid() 方法返回 True,否则返回 False
        """
        if serializer.is_valid():
            # 校验通过,将数据添加到数据库
            # new_book = Book.objects.create(**serializer.validated_data)
            # 一般如果数据库表关系复杂一点的话,那么保存数据到数据库的操作应该抽取出来
            # 应该调用 序列化器实例对象的 save() 方法
            serializer.save()

            # 向前端返回这个书籍
            # 数据已经通过校验,直接将传过来的数据序列化之后返回
            return Response(serializer.data)
        else:
            # 校验失败,返回错误信息
            Response(serializer.errors)

serializers.save() 方法分析

"""
            serializer.save() 的源码
            先看序列化器 BookSerializer ,类中没有 save() 方法,
                class BookSerializer(serializers.Serializer):
                    # ...

                    # 重写父类中的 create 方法,实现自己的数据保存逻辑
                    # create 方法需要返回值,因为在源码中 save 方法需要接收 create 方法的返回值
                    def create(self, validated_data):
                        new_book = Book.objects.create(**self.validated_data)
                        return new_book

            再找 BookSerializer 的父类 Serializer,也没有 save() 方法
                class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
                    # ...
            再找 Serializer 的父类 BaseSerializer,找到了 save() 方法
                class BaseSerializer(Field):
                    # create() 方法中什么都没做,而是直接抛出了异常,这样做的目的就是为了让子类重写该方法
                    def create(self, validated_data):
                        raise NotImplementedError('`create()` must be implemented.')

                    def save(self, **kwargs):
                        # ...
                        # 此时 self 指的是 BookSerializer 的实例对象 serializer
                        # instance 表示的是要序列化的数据,因为在 post 方法中进行的是反序列化
                        # 所以传的是 data 关键字参数,没有传 instance
                        # 所以走的是 else 中的代码
                        # 也就是说如果要进行序列化,传 instance 参数,调用 save 方法时走的是 if 中的代码
                        # 如果进行的是反序列化,传的是 data 参数,调用 save 方法走的就是 else 中的代码
                        if self.instance is not None:
                            self.instance = self.update(self.instance, validated_data)
                            assert self.instance is not None, (
                                '`update()` did not return an object instance.'
                            )
                        else:
                            # self.create() 方法的查找:通过一层层的查找最后也是在 BaseSerializer 类中找到了
                            self.instance = self.create(validated_data)
                            assert self.instance is not None, (
                                '`create()` did not return an object instance.'
                            )

                        return self.instance
            """文章来源地址https://www.toymoban.com/news/detail-667634.html

到了这里,关于rest_framework(3)序列化和反序列化(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • web应用模式、API接口、接口测试工具postman、如何在浏览器中测试、restful规范、序列化反序列化、基于Django原生编写五个接口、drf介绍和快速使用、drf之APIView源码分析

    目录 一、web应用模式 二、API接口 三、接口测试工具postman postman介绍 postman下载与使用 四、如何在浏览器中测试 五、restful规范(重要) 六、序列化反序列化 七、基于Django原生编写五个接口 八、drf介绍和快速使用 概念 特点(了解一下) 安装 使用drf编写五个接口 九、drf之API

    2024年02月05日
    浏览(39)
  • 【django2.0之Rest_Framework框架一】rest_framework序列器介绍

    Django RestFramework(简称DRF) 提供了序列化器Serialzier的定义,可以帮助我们简化序列化与反序列化的过程,不仅如此,还提供丰富的类视图、扩展类、视图集来简化视图的编写工作。REST framework还提供了认证、权限、限流、过滤、分页、接口文档等功能支持。 github地址: https://

    2024年02月07日
    浏览(32)
  • Django--DRf---序列化器:序列化器嵌套

    模型表: 1、方式一:通过source来获取指定字段数据 【一对多和一对一的】 1.1、一对多 外键方 1.2、多对多 外键方 【不适应】 2、方式二:通过外键=序列化类() 【适用所有关系】 2.1、多对多:外键在这里 序列化器: 视图类: 2.2、一对多,外键方 【学生表,嵌套班级】 3、

    2024年02月01日
    浏览(23)
  • Unity-序列化和反序列化

    序列化是指把对象转换为字节序列的过程,而反序列化是指把字节序列恢复为对象的过程。序列化最主要的用途就是传递对象和保存对象。 在Unity中保存和加载、prefab、scene、Inspector窗口、实例化预制体等都使用了序列化与反序列化。 1 自定义的具有Serializable特性的非抽象、

    2024年01月24日
    浏览(39)
  • 什么是序列化和反序列化?

    JSON(JavaScript Object Notation)和XML(eXtensible Markup Language)是两种常用的数据交换格式,用于在不同系统之间传输和存储数据。 JSON是一种轻量级的数据交换格式,它使用易于理解的键值对的形式表示数据。JSON数据结构简单明了,易于读写和解析,是基于JavaScript的一种常用数据

    2024年02月09日
    浏览(40)
  • 【Linux】序列化和反序列化

    在网络编程中,直接使用 结构体 进行数据传输会出错,因为 本质上socket无法传输结构体 ,我们只有将结构体装换为字节数组,或者是字符串格式来传输,然后对端主机收到了数据,再将其转化为结构体,这就是序列化和反序列化的过程! 序列化 (Serialization)是将对象的状态

    2024年02月10日
    浏览(28)
  • Java序列化和反序列化

    目录 一、序列化和反序列化 二、Java序列化演示 三、反序列化漏洞 1、含义 ​序列化就是内存中的对象写入到IO流中,保存的格式可以是二进制或者文本内容。反序列化就是IO流还原成对象。 2、用途 (1)传输网络对象 (2)保存Session 1、序列化 java.io.ObjectOutputStream代表对象

    2023年04月25日
    浏览(25)
  • Java序列化和反序列化机制

    在阅读 ArrayList 源码的时候,注意到,其内部的成员变量动态数组 elementData 被Java中的 transient 修饰 transient 意味着Java在序列化时会跳过该字段(不序列化该字段) 而Java在默认情况下会序列化类(实现了 Java.io.Serializable 接口的类)的所有非瞬态(未被 transient 修饰

    2024年03月15日
    浏览(35)
  • java中的序列化和反序列化

    objectOutputStream 对象的序列化,以流的形式将对象写入文件 构造方法: objectOutputStream(OutputStream out) 传入一个字节输入流创建objectOutputStream对象 成员方法: void writeObject(object obj) 将指定的对象写入objectOutputStream 使用步骤: 创建一个类,这个类实现Serializable接口,Serializable是一

    2024年02月14日
    浏览(25)
  • TCP定制协议,序列化和反序列化

    目录 前言 1.理解协议 2.网络版本计算器 2.1设计思路 2.2接口设计 2.3代码实现: 2.4编译测试 总结         在之前的文章中,我们说TCP是面向字节流的,但是可能对于面向字节流这个概念,其实并不理解的,今天我们要介绍的是如何理解TCP是面向字节流的,通过编码的方式,自

    2024年02月12日
    浏览(23)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包