自定义序列化器(反序列化操作)

本文详细介绍了Django REST framework中反序列化的操作流程,包括校验过程、新建及更新模型对象的方法,并提供了实例演示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、反序列化操作之校验
1.1、标准校验操作流程
  • (1)、获取前端传参(字典)
    • book_info = {"btitle": "三体", "bpub_date": "1999-9-9"}
  • (2)、实例化序列化器对象
    • bs = BookInfoSerializer(data=book_info)
      • data参数指定被校验的字典数据
  • (3)、启动校验流程
    • bs.is_valid(): 默认通过返回值为True或False表示校验成功或者失败;
    • is_valid(raise_exception=True): 通过抛出ValidationError来表示校验失败;
  • (4)、校验结果
    • 成功:通过bs.validated_data获取有效数据
    • 失败:通过bs.errors获取失败提示信息
1.2、校验步骤(经过哪些校验)
  • (1)约束条件校验(见下表)

  • (2)类型校验

  • (3)自定义校验(三种)(针对某一字段进行校验:validatorsvalidate_<字段名>、全字段校验:validate

  • 参数名称作用
    max_length最大长度
    min_lenght最小长度
    allow_blank是否允许为空
    trim_whitespace是否截断空白字符
    max_value最大值
    min_value最小值
    read_only表明该字段仅用于序列化输出,默认False
    write_only表明该字段仅用于反序列化输入,默认False
    required表明该字段在反序列化时必须输入,默认True
    default反序列化时使用的默认值
    allow_null表明该字段是否允许传入None,默认False
  • 1.2.2、需求:对书名btitle进行名字约束,书名必须包含django
    自定义校验一validators

  • 在序列器前面定义函数check_btitle,在约束中使用validators=[check_btitle]j进行调用约束

from rest_framework import serializers


def check_btitle(value):
    """
    功能:自定义校验字段btitle
    :param value: btitle字段经过前序(约束、类型)校验后的值
    :return: 无
    """
    if 'django' not in value:
        raise serializers.ValidationError('这不是一本关于django的书')


class BookInfoSerializer(serializers.Serializer):
    """图书数据序列化器"""
    id = serializers.IntegerField(label='ID', read_only=True)
    btitle = serializers.CharField(label='名称', min_length=2, validators=[check_btitle])
    bpub_date = serializers.DateField(label='发布日期', required=False)

    bread = serializers.IntegerField(label='阅读量', required=False)
    bcomment = serializers.IntegerField(label='评论量', required=False)
    is_delete = serializers.BooleanField(required=False)
    image = serializers.ImageField(label='图片', required=False)
  • 测试:如果前端传来的值是’三体’,该值没有包含django,因此校验失败False
>>> from books_test.serializers import *
>>> book_info = {"btitle": "三体", "bpub_date": "1999-9-9"}
>>> bs = BookInfoSerializer(data = book_info)
>>> bs.is_valid()
False
>>> 

自定义校验二validate_<字段名>
在序列化器里面定义函数def validate_btitle(self, value)

    # 重写序列化器特定名称的方法,针对特定字段单独自定义校验,函数名称:validate_<被校验字段名>
    def validate_btitle(self, value):
        """
        针对btitle自定义校验
        :param value: btitle字段经过前序校验的值
        :return: 返回经过当前校验的当前字段的值
        """
        if "django" not in value:
            raise serializers.ValidationError("这不是一本关于django的书")

        # 切记,一定要返回字段的有效值,如果不返回会造成当前字段数据丢失
        return value

自定义校验三validate
在序列化器里面定义函数def validate(self, attrs)

    # 校验的最终步骤,全字段校验,控制最终有效数据
    def validate(self, attrs):
        """
        功能:全字段校验
        :param attrs: 经过前序校验的所有字段及其值 --> {"btitle": "django精通", "bpub_date": date(1999,9,9)....}
        :return: 返回最终的有效数据 就是 validated_data
        """
        btitle = attrs.get('btitle')
        if 'django' not in btitle:
            raise serializers.ValidationError('这不是一本关于django的书')
        # 相同方式对别的字段校验...略
        # 返回最终的有效数据,如果不返回,后果就是丢失最终的有效数据
        return attrs
  • 校验流程图示
book_info={'btitle':'django精通'...}
bs=BookInfoSerializer(data=book_info)
当且仅当校验成功
1、获取有效数据
2、实例化序列化器对象
3、启动校验流程: bs.is_valid()
4、获取最终有效数据: bs.validated_data
约束条件校验
类型校验
validators校验
validate_<字段名>校验
validate校验

2、反序列化操作之标准新建/更新操作流程

2.1、新建操作流程

  • 在序列化器内重写create方法,实现新建
    def create(self, validated_data):
        """
        功能:基于校验成功的有效数据,新建模型类对象保存数据库
        :param validated_data: 最终的有效数据(字典)
        :return: 返回新建的模型类对象
        """
        instance = BookInfo.objects.create(**validated_data)
        return instance
  • 终端测试:
>>>from books_test.serializer import *
>>># 1、获取前端传值
>>> book_infoo = {'btitle': '三体', 'bpub_date': '1997-6-6'}
>>># 2、实例化序列化器对象
>>> bs = BookInfoSerializer(data=book_infoo)
>>>#3、启动校验流程(步骤)
>>> bs.is_valid()
True
>>># 4、新建:save()方法本质是间接调用序列化器重写的create方法,自动传入有效数据完成新建
>>> bs.save()
<BookInfo: 三体>
>>> 

2.2、更新操作流程

  • 在序列化器内重写update方法,实现更新(全更新)
    setattr()ORM内置函数作用:更新某一模型类对象
   def update(self, instance, validated_data):
        """
        功能:更新模型类对象
        :param instance: 被更新的模型类对象
        :param validated_data:用于更新的有效数据
        :return: 返回被更新之后的模型类对象
        """
        # 由于有些字段是非必传的,所以我们不确定非必传字段有没有。因此需要for遍历
        for field, value in validated_data.items():
            setattr(instance, field, value)  # setattr():更新指定对象instance数据

        instance.save()
        return instance
>>> from books_test.serializers import *
>>>#1、获取前端传值
>>> book_infoo = {'btitle': '三体后传', 'bpub_date': '1997-6-6'}
>>># 2、获取被更新对象(书)
>>> book = BookInfo.objects.get(btitle='三体')
>>> # 3、实例化序列化器对象(传入前端传来的值,和被更新的对象)
>>> bs = BookInfoSerializer(data=book_infoo,instance=book)
>>> bs.is_valid()
True
>>># 4、更新
>>> bs.save()
<BookInfo: 三体后传>
>>> 
2.3、完整序列化器反序列化操作流程示意图
只传入data(新建)
传入instance和data(更新)
只传入data
同时传入instance和data
1、实例化序列化器对象:bs=Serializer()
2、启动校验流程:bs.is_valid()
前提:校验成功(获取有效数据)
约束条件校验
类型校验
validators校验
validate_<字段名>校验
validate校验
3、新建/更新模型类对象:bs.save()
新建模型类对象,调用序列化器create方法
更新模型类对象,调用序列化器update方法
2.4、补充说明
  • (1)PrimaryKeyRelatedField作用于序列化的时候,把关联对象序列化成主键

  • (2)PrimaryKeyRelatedField作用与反序列化的时候,把主键反序列化成关联的对象;
    在这里插入图片描述

  • (3)全更新
    全更新其本质是 —— 全校验,必要字段必传必校验。默认情况是全更新

  • (4)部分更新
    部分更新其本质是 —— 部分校验,必要字段可传可不传,传什么就校验什么

  • Serializer(instance=模型类对象,data=参数,partial=True): 实例化序列器对象时加上partial=True表明序列化器后续的校验逻辑为部分校验;

>>> book_infoo = {'bread':100}
>>> book = BookInfo.objects.get(btitle='三体后传')
>>> bs = BookInfoSerializer(data=book_infoo,instance=book,partial=True)
>>> bs.is_valid()
True
>>> bs.save()
<BookInfo: 三体后传>
>>> 

  • (5)save()方法传递关键字参数
    作用:传递的关键字参数,会被合并到validated_data有效数据中,作用于createupdate方法!
    示例:基于上面的部分更新测试代码,最后一句bs.save()改成如下代码:
bs.save(bcomment=200, btitle = 三体前传)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值