Django(44)drf序列化源码分析[通俗易懂]

Django(44)drf序列化源码分析[通俗易懂]序列化与反序列化一般后端数据返回给前端的数据格式都是json格式,简单易懂,但是我们使用的语言本身并不是json格式,像我们使用的Python如果直接返回给前端,前端用的javascript语言是识

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

序列化与反序列化

  一般后端数据返回给前端的数据格式都是json格式,简单易懂,但是我们使用的语言本身并不是json格式,像我们使用的Python如果直接返回给前端,前端用的javascript语言是识别不出的,所以我们需要把python语言转换为通用的json格式的数据,在django中就是将orm模型或者queryset对象转换成字典,再由字典转换成json,整个过程就是序列化。

  当用户通过在form表单中填写的数据,发送请求给后端,将数据提交给后端数据库,这个过程就是反序列化。反序列化的时候,我们需要去验证前端提交的数据是否符合后端制定的规范,符合才进行入库。
 

drf的序列化类

drf的序列化类有3个

  • Serializer
  • ModelSerializer(使用最多的)
  • ListSerializer

我们使用最多的就是ModelSerializer,这三个序列化类都继承自BaseSerializer,虽然我们项目中99%都是使用的ModelSerializer,但是光知道怎么使用,是没有灵魂的,我们还需要去了解源码,多看源码能迅速提高代码能力。
 

BaseSerializer源码分析

源码如下:

class BaseSerializer(Field):
    def __init__(self, instance=None, data=empty, **kwargs):
     
    def __new__(cls, *args, **kwargs)

    def __class_getitem__(cls, *args, **kwargs)

    @classmethod
    def many_init(cls, *args, **kwargs):

    def to_internal_value(self, data):

    def to_representation(self, instance):

    def update(self, instance, validated_data):

    def create(self, validated_data):

    def save(self, **kwargs):

    def is_valid(self, raise_exception=False):

    @property
    def data(self):

    @property
    def errors(self)

    @property
    def validated_data(self)

我们分析几个重要的方法,没必要每个方法都了解,分析的都是后面要用到的
 

__init__方法

def __init__(self, instance=None, data=empty, **kwargs):
    self.instance = instance 
    if data is not empty:
        self.initial_data = data
    self.partial = kwargs.pop('partial', False)
    self._context = kwargs.pop('context', {})
    kwargs.pop('many', None)
    super().__init__(**kwargs)

初始化方法,有4个参数

  • self:本身自己
  • instance:实例,默认为None
  • data:数据,默认为empty
  • **kwargs:不定长字典
     

create

def create(self, validated_data):
    raise NotImplementedError('`create()` must be implemented.')

定义了一个create方法,参数为validated_data,方法抛出了一个异常,意思是create方法没有定义,如果要继承BaseSerializer,那就必须定义create方法,否则就会抛出异常
 

update

def update(self, instance, validated_data):
    raise NotImplementedError('`update()` must be implemented.')

定义了一个update方法,有2个参数

  • instance:实例,更新数据的时候,需要知道更新的是哪个实例化对象
  • validated_data:已验证的数据,前端传入的字段需要进行验证

此方法抛出了一个异常,意思是update方法没有定义,如果要继承BaseSerializer,那就必须定义update方法,否则就会抛出异常
 

is_valid

def is_valid(self, raise_exception=False):
    # 如果self对象没有initial_data属性,那么将无法调用该方法,如果需要有initial_data,那么实例化对象必须传入data参数
    assert hasattr(self, 'initial_data'), (
        'Cannot call `.is_valid()` as no `data=` keyword argument was '
        'passed when instantiating the serializer instance.'
    )

    if not hasattr(self, '_validated_data'):
        try:
            self._validated_data = self.run_validation(self.initial_data)
        except ValidationError as exc:
            self._validated_data = {}
            self._errors = exc.detail
        else:
            self._errors = {}

    if self._errors and raise_exception:
        raise ValidationError(self.errors)

    return not bool(self._errors)

这个方法是验证从前端传输过来的字段是否验证成功,如果我们的实例化对象没有传入data参数,将会无法调用is_valid,这个方法大多数用在反序列化的时候
 

save

def save(self, **kwargs):
    # 调用save()方法前必须先调用is_valid()
    assert hasattr(self, '_errors'), (
        'You must call `.is_valid()` before calling `.save()`.'
    )
    # 不能对无效的数据调用save()方法
    assert not self.errors, (
        'You cannot call `.save()` on a serializer with invalid data.'
    )
    # 防止没有正确使用save方法
    # Guard against incorrect use of `serializer.save(commit=False)`
    assert 'commit' not in kwargs, (
        "'commit' is not a valid keyword argument to the 'save()' method. "
        "If you need to access data before committing to the database then "
        "inspect 'serializer.validated_data' instead. "
        "You can also pass additional keyword arguments to 'save()' if you "
        "need to set extra attributes on the saved model instance. "
        "For example: 'serializer.save(owner=request.user)'.'"
    )
    # 访问serializer.data后就不能调用save方法了,如果你需要在提交到数据库之前访问数据,那么请使用serializer.validated_data
    assert not hasattr(self, '_data'), (
        "You cannot call `.save()` after accessing `serializer.data`."
        "If you need to access data before committing to the database then "
        "inspect 'serializer.validated_data' instead. "
    )
    # 创建已验证的数据对象
    validated_data = {**self.validated_data, **kwargs}
    
    # 如果instance不为空
    if self.instance is not None:
        # instance对象将更新为validated_data里的内容
        self.instance = self.update(self.instance, validated_data)
        assert self.instance is not None, (
            '`update()` did not return an object instance.'
        )
    else:
        # 如果instance为空,那么则创建对象,对象的内容为validated_data
        self.instance = self.create(validated_data)
        assert self.instance is not None, (
            '`create()` did not return an object instance.'
        )

    return self.instance
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/165779.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • RSA加密算法解读

    RSA加密算法解读图为RSA公开密钥算法的发明人,从左到右RonRivest,AdiShamir,LeonardAdleman.照片摄于1978年  RSA加密算法是最常用的非对称加密算法,CFCA在证书服务中离不了它。但是有不少新来的同事对它不太了解,恰好看到一本书中作者用实例对它进行了简化而生动的描述,使得高深的数学理论能够被容易地理解。我们经过整理和改写特别推荐给大家阅读,希望能够对时间…

  • github网速很慢(github很慢)

    下面是转载其他人的信息,实测通过换URL确实速度飞快!近日,我在Github上下载源码,真的鸡肋,慢的一匹,通过以下方式,让我下载Github速度飞快,因为刚好有代理,就用的第一种方式,而后面几种方式参考自网上的一些方案,自己也尝试了一下,有点用,就贴出来,给大家提升一下工作效率,如果您也有类似的问题,欢迎转发,收藏~同时,欢迎留言区写下自己用过或者本文没有提到的方案,一起完善~1.有代理只需要针对github设置代理即可,这里以ss为例子:#只对github.comgitconfig

  • Django(39)使用redis配置缓存[通俗易懂]

    Django(39)使用redis配置缓存[通俗易懂]前言动态网站的基本权衡是,它们是动态的。每次用户请求页面时,Web服务器都会进行各种计算-从数据库查询到模板呈现再到业务逻辑-以创建站点访问者看到的页面。从处理开销的角度来看,这比标准的文件

  • stderr和stdout详细解说

    stderr和stdout详细解说cstdio>objectstderrFILE*stderr;StandarderrorstreamThestandarderrorstreamisthedefaultdestinationforerrormessagesandotherdiagnosticwarnings.Likestdout,itisusuall

    2022年10月26日
  • k8s支持的存储_外部存储数据库

    k8s支持的存储_外部存储数据库k8sPV和PVC概述PVPVC生命周期配置存储ConfigMapSecretPV和PVC概述前面我们已经学习了使用NFS提供存储,此时就要求用户会搭建NFS系统,并且会在yaml配置nfs。由于kubernetes支持的存储系统有很多,要求客户全部掌握,显然不现实。为了能够屏蔽底层存储实现的细节,方便用户使用,kubernetes引入了PV和PVC两种资源对象。PV(Persistent Volume)是持久化卷的意思,是对底层的共享存储的一种抽象。一般情况下PV由kubernetes管理员进行创

  • Python 二次开发 AutoCAD 简介「建议收藏」

    Python 二次开发 AutoCAD 简介「建议收藏」一、前沿cad是python是ActiveX是pyautocad模块由俄罗斯工程师开发,因参考实例较少,工程需要,现将模块中一些基本的用法,做出简要说明,叙述力求简洁明了,因个人水平有限,文中难免有所疏漏,还请各位大神不吝批评指正。…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号