20-Django REST framework-Serializer序列化器

news2024/9/25 13:18:53

Serializer序列化器

      • 前言
      • 序列化器作用
      • 定义Serializer
        • 定义方法
        • 字段与选项
        • 创建Serializer对象
      • 序列化使用
        • 基本使用
        • 增加额外字段
        • 关联对象序列化
      • 反序列使用
      • 模型类序列化器ModelSerializer
        • 指定字段


前言

  • 本篇来学习Serializer序列化器知识

序列化器作用

  • 进行数据的校验
  • 对数据对象进行转换

定义Serializer

定义方法

  • 模型
# models.py

from django.db import models


# Create your models here.
# 准备书籍列表信息的模型类
class BookInfo(models.Model):
    # 创建字段,字段类型
    name = models.CharField(max_length=20, verbose_name='名称')  # verbose_name admin管理后台使用
    pub_date = models.DateField(verbose_name='发布日期', null=True)
    readcount = models.IntegerField(default=0, verbose_name='阅读量')
    commentcount = models.IntegerField(default=0, verbose_name='评论量')
    is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')

    class Meta:
        db_table = 'bookinfo'  # 指明数据库表名
        verbose_name = '图书'  # 在admin站点中显示的名称

    def __str__(self):
        """定义每个数据对象的显示信息"""
        return self.name
  • 序列化器
# -*- coding: utf-8 -*-
# @Time    : 2022/9/24
# @Author  : 大海
# serializers.py

from rest_framework import serializers
from book.models import BookInfo

class BookInfoSerializer(serializers.Serializer):
    """图书数据序列化器"""
    name = serializers.CharField(max_length=20, label='名称')  # label DRF接口页面展示使用
    pub_date = serializers.DateField(label='发布日期', required=True)
    readcount = serializers.IntegerField(required=False, label='阅读量')
    commentcount = serializers.IntegerField(required=False, label='评论量')
    is_delete = serializers.BooleanField(required=False, label='逻辑删除')

字段与选项

  • 常用字段类型
    在这里插入图片描述
  • 选项参数
参数名称作用
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
validators该字段使用的验证器
error_messages包含错误编号与错误信息的字典
label用于HTML展示API页面时,显示的字段名称
help_text用于HTML展示API页面时,显示的字段帮助提示信息

创建Serializer对象

Serializer的构造方法为:

Serializer(instance=None, data=empty, **kwarg)

说明:
1)用于序列化时,将模型类对象传入instance参数
2)用于反序列化时,将要被反序列化的数据传入data参数
3)除了instance和data参数外,在构造Serializer对象时,还可通过context参数额外添加数据,如
serializer = AccountSerializer(account, context={‘request’: request})
通过context参数附加的数据,可以通过Serializer对象的context属性获取。

序列化使用

基本使用

  • 进入Django shell模式
python manage.py shell
  1. 查询一个图书对象
from book.models import BookInfo

book = BookInfo.objects.get(id=1)
  1. 构造序列化器
from book.serializers import BookInfoSerializer

serializer = BookInfoSerializer(book)
  1. 获取序列化数据
serializer.data
  1. 如果要被序列化的是包含多条数据的查询集QuerySet,可以通过添加many=True参数补充说明
books = BookInfo.objects.all()
serializer = BookInfoSerializer(books,many=True)
serializer.data

在这里插入图片描述
在这里插入图片描述

增加额外字段

# serializers.py
from rest_framework import serializers

class BookInfoSerializer(serializers.Serializer):
    """图书数据序列化器"""
    name = serializers.CharField(max_length=20, label='名称')  # label DRF接口页面展示使用
    pub_date = serializers.DateField(label='发布日期', required=True)
    readcount = serializers.IntegerField(required=False, label='阅读量')
    commentcount = serializers.IntegerField(required=False, label='评论量')
    is_delete = serializers.BooleanField(required=False, label='逻辑删除')
    hello = serializers.CharField()  # 增加模型中不存在字段
  • 进入Django shell模式
python manage.py shell
from book.models import BookInfo

book = BookInfo.objects.get(id=1)

book.hello = '666'

from book.serializers import BookInfoSerializer

serializer = BookInfoSerializer(book)

serializer.data

在这里插入图片描述

关联对象序列化

  • models.py
from django.db import models


# Create your models here.
# 准备书籍列表信息的模型类
class BookInfo(models.Model):
    # 创建字段,字段类型
    name = models.CharField(max_length=20, verbose_name='名称')  # verbose_name admin管理后台使用
    pub_date = models.DateField(verbose_name='发布日期', null=True)
    readcount = models.IntegerField(default=0, verbose_name='阅读量')
    commentcount = models.IntegerField(default=0, verbose_name='评论量')
    is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')

    class Meta:
        db_table = 'bookinfo'  # 指明数据库表名
        verbose_name = '图书'  # 在admin站点中显示的名称
	
	def __str__(self):
        """定义每个数据对象的显示信息"""
        return self.name


# 准备人物列表信息的模型类
class PeopleInfo(models.Model):
    # 定义一个有序字典
    GENDER_CHOICES = (
        (0, 'male'),
        (1, 'female')
    )
    name = models.CharField(max_length=20, verbose_name='名称')
    gender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name='性别')
    description = models.CharField(max_length=200, null=True, verbose_name='描述信息')
    is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')
    # 外键 ForeignKey
    # 系统会字典为外加添加  id
    # 外键的级联操作  1对多 (书籍对人物)
    # CASCADE:删除主表数据时连通一起删除外键表中数据
    book = models.ForeignKey(BookInfo, on_delete=models.CASCADE, verbose_name='图书')

    class Meta:
        db_table = 'peopleinfo'
        verbose_name = '人物信息'
  • serializers.py
# -*- coding: utf-8 -*-
# @Time    : 2022/9/24
# @Author  : 大海
from abc import ABC

from rest_framework import serializers
from book.models import BookInfo


class BookInfoSerializer(serializers.Serializer):
    """图书数据序列化器"""
    name = serializers.CharField(max_length=20, label='名称')  # label DRF接口页面展示使用
    pub_date = serializers.DateField(label='发布日期', required=True)
    readcount = serializers.IntegerField(required=False, label='阅读量')
    commentcount = serializers.IntegerField(required=False, label='评论量')
    is_delete = serializers.BooleanField(required=False, label='逻辑删除')
    # hello = serializers.CharField()  # 增加模型中不存在字段


class HeroInfoSerializer(serializers.Serializer):
    """英雄数据序列化器"""
    GENDER_CHOICES = (
        (0, 'female'),
        (1, 'male')
    )
    id = serializers.IntegerField(label='ID', read_only=True)
    name = serializers.CharField(label='名字', max_length=20)
    gender = serializers.ChoiceField(choices=GENDER_CHOICES, label='性别', required=False)
    description = serializers.CharField(label='描述信息', max_length=200, required=False, allow_null=True)
    is_delete = serializers.BooleanField(label='是否删除', required=False)
    # 默认序列化外键id
    # book = serializers.PrimaryKeyRelatedField(label='书籍', read_only=True)
    # 序列化关联模型的__str__方法返回值序列化
    # book = serializers.StringRelatedField(label='书籍', read_only=True)
    # 关联模型序列化器所有字段序列化
    book = BookInfoSerializer()
    # book = serializers.PrimaryKeyRelatedField(label='书籍', queryset=BookInfo.objects.all())


#  book = serializers.PrimaryKeyRelatedField(label='书籍', read_only=True) 默认序列化外键id
In [1]: from book.models import BookInfo,PeopleInfo

In [2]: from book.serializers import BookInfoSerializer,HeroInfoSerializer

In [3]: hero = PeopleInfo.objects.get(id=1)

In [4]: serializer = HeroInfoSerializer(instance=hero)

In [5]: serializer.data
Out[5]: {'id': 1, 'name': '郭靖', 'gender': 1, 'description': '降龙十八掌', 'is_delete': False, 'book': 1}

# book = serializers.StringRelatedField(label='书籍', read_only=True) 序列化关联模型的__str__方法返回值序列化
In [1]: from book.serializers import BookInfoSerializer,HeroInfoSerializer
   ...: 
   ...: from book.models import BookInfo,PeopleInfo
   ...: 
   ...: hero = PeopleInfo.objects.get(id=1)
   ...: 
   ...: serializer = HeroInfoSerializer(instance=hero)

In [2]: serializer.data
Out[2]: {'id': 1, 'name': '郭靖', 'gender': 1, 'description': '降龙十八掌', 'is_delete': False, 'book': '射雕英雄传'}

# book = BookInfoSerializer()
In [1]: from book.serializers import BookInfoSerializer,HeroInfoSerializer
   ...: 
   ...: from book.models import BookInfo,PeopleInfo
   ...: 
   ...: hero = PeopleInfo.objects.get(id=1)
   ...: 
   ...: serializer = HeroInfoSerializer(instance=hero)

In [2]: serializer.data 关联模型序列化器所有字段序列化
Out[2]: {'id': 1, 'name': '郭靖', 'gender': 1, 'description': '降龙十八掌', 'is_delete': False, 'book': OrderedDict([('nam
e', '射雕英雄传'), ('pub_date', '1980-05-01'), ('readcount', 12), ('commentcount', 34), ('is_delete', False)])}

反序列使用

  • 进入Django shell模式
: data = {
   ...:     'name': '北漂纪实',
   ...:     'pub_date':'2022-12-10'
   ...: }

In [2]: from book.serializers import BookInfoSerializer

In [3]: serializer = BookInfoSerializer(data=data)

In [4]: serializer.is_valid(raise_exception=True)  # 调用序列化器校验方法
Out[4]: True

In [5]: serializer.errors   # 获取错误信息
Out[5]: {}

In [6]: serializer.validated_data  # 获取反序列化后的数据
Out[6]: OrderedDict([('name', '北漂纪实'), ('pub_date', datetime.date(2022, 12, 10))])
  • 单个字段校验
class BookInfoSerializer(serializers.Serializer):
    """图书数据序列化器"""
    name = serializers.CharField(max_length=20, label='名称')  # label DRF接口页面展示使用
    pub_date = serializers.DateField(label='发布日期', required=True)
    readcount = serializers.IntegerField(required=False, label='阅读量')
    commentcount = serializers.IntegerField(required=False, label='评论量')
    is_delete = serializers.BooleanField(required=False, label='逻辑删除')
    # hello = serializers.CharField()  # 增加模型中不存在字段
    peopleinfo_set = serializers.PrimaryKeyRelatedField(many=True, read_only=True)  # 序列化id
    # peopleinfo_set = HeroInfoSerializer(many=True)  # 一关联多 需要指定many=true 全部值

    def validate_name(self, value):
        """序列化器中单个字段校验"""
        if 'django' not in value.lower():
            raise serializers.ValidationError("图书不是关于Django的")
        return value
  • shell 模式
 from book.serializers import BookInfoSerializer

In [2]: data = {
   ...:     'name': '北漂纪实',
   ...:     'pub_date':'2022-12-10'
   ...: }

In [3]: serializer = BookInfoSerializer(data=data)
serializer.is_valid(raise_exception=True)
   ...: 
   ...: 
---------------------------------------------------------------------------
ValidationError                           Traceback (most recent call last)
<ipython-input-5-c24be91bdde3> in <module>
----> 1 serializer.is_valid(raise_exception=True)
      2

D:\Python39\lib\site-packages\rest_framework\serializers.py in is_valid(self, raise_exception)
    233
    234         if self._errors and raise_exception:
--> 235             raise ValidationError(self.errors)
    236
    237         return not bool(self._errors)

ValidationError: {'name': [ErrorDetail(string='图书不是关于Django的', code='invalid')]}
  • serializers.py
class BookInfoSerializer(serializers.Serializer):
    """图书数据序列化器"""
    name = serializers.CharField(max_length=20, label='名称')  # label DRF接口页面展示使用
    pub_date = serializers.DateField(label='发布日期', required=True)
    readcount = serializers.IntegerField(required=False, label='阅读量')
    commentcount = serializers.IntegerField(required=False, label='评论量')
    is_delete = serializers.BooleanField(required=False, label='逻辑删除')
    # hello = serializers.CharField()  # 增加模型中不存在字段
    peopleinfo_set = serializers.PrimaryKeyRelatedField(many=True, read_only=True)  # 序列化id

    # peopleinfo_set = HeroInfoSerializer(many=True)  # 一关联多 需要指定many=true 全部值

    def validate_name(self, value):
        """序列化器中单个字段校验
        validate_<field_name>
        """
        if 'django' not in value.lower():
            raise serializers.ValidationError("图书不是关于Django的")
        return value

    def validate(self, attrs):
        """多个字段校验
        attrs 传过来的数据 字典类型
        """
        bread = attrs['readcount']
        bcomment = attrs['commentcount']
        if bread < bcomment:
            raise serializers.ValidationError('阅读量小于评论量')
        return attrs

    def create(self, validated_data):
        """新建"""
        return BookInfo.objects.create(**validated_data)

    def update(self, instance, validated_data):
        """更新,instance为要更新的对象实例"""
        instance.name = validated_data.get('name', instance.name)
        instance.readcount = validated_data.get('readcount', instance.readcount)
        instance.commentcount = validated_data.get('commentcount', instance.commentcount)
        instance.save()
        return instance
  • 修改
from book.serializers import BookInfoSerializer

In [4]: from book.models import BookInfo

In [5]: book = BookInfo.objects.get(id=5)

In [6]: data = {
   ...:     'name': '北漂纪实007-django',
   ...:     'pub_date':'2022-12-10',
   ...:     'readcount': 20,
   ...:     'commentcount':10
   ...: }

In [7]: serializer = BookInfoSerializer(book,data)

In [8]: serializer.is_valid(raise_exception=True)
Out[8]: True

In [9]: serializer.save()
Out[9]: <BookInfo: 北漂纪实007-django>

模型类序列化器ModelSerializer

  • 模型序列化器
from rest_framework import serializers
from book.models import BookInfo


class BookInfoSerializer(serializers.ModelSerializer):
    """图书数据序列化器"""

    class Meta:
        model = BookInfo  # 指定模型
        fields = '__all__'  # 指定序列化器包含所有字段

指定字段

  1. 使用fields来明确字段,__all__表名包含所有字段,也可以写明具体哪些字段,如
class BookInfoSerializer(serializers.ModelSerializer):
    """图书数据序列化器"""
    class Meta:
        model = BookInfo
        fields = ['id', 'name', 'bpub_date']
  1. 使用exclude可以明确排除掉哪些字段
class BookInfoSerializer(serializers.ModelSerializer):
    """图书数据序列化器"""
    class Meta:
        model = BookInfo
        exclude = ['readcount']
  1. 指明只读字段
class BookInfoSerializer(serializers.ModelSerializer):
    """图书数据序列化器"""
    class Meta:
        model = BookInfo
        fields = ('id', 'btitle', 'bpub_date''bread', 'bcomment')
        read_only_fields = ('id', 'readcount')
  1. 修改选项参数
lass BookInfoSerializer(serializers.ModelSerializer):
    """图书数据序列化器"""
    class Meta:
        model = BookInfo
        fields = ('id', 'btitle', 'bpub_date', 'bread', 'bcomment')
        extra_kwargs = {
            'readcount': {'min_value': 0, 'required': True},
            'commentcount': {'min_value': 0, 'required': True},
        }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/78562.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]计算机毕业设计基于VUE的网上订餐系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【代码审计-JAVA】基于javaweb框架开发的

目录 一、javaweb三大框架 1、Spring&#xff08;开源分层的框架&#xff09; 2、Struts&#xff08;MVC设计模式&#xff09; 3、Hibernate&#xff08;开源的对象关系映射框架&#xff09; 二、特征 1、结构 2、Servlet 三、重要文件 1、web.xml 2、pom.xml 3、web…

【文献研究】班轮联盟下合作博弈的概念

前言&#xff1a;以下是本人做学术研究时搜集整理的资料&#xff0c;供有相同研究需求的人员参考。 1. 合作博弈的一些概念 合作博弃中比较重要的问题是共赢状态下的利润分配问题&#xff0c;这关系到联盟的合作机制能否长期有效。这里首先介绍几个重要的概念&#xff1a; &…

174.Django中文件上传和下载

1. 文件上传和下载环境搭建 创建django项目和子应用urls中包含子应用&#xff0c;在子应用中创建urls.py配置数据库sqlite3&#xff08;默认就是&#xff0c;无需配置&#xff09;配置settings&#xff0c;上传文件目录编写模型代码&#xff08;下面给出&#xff09;模型的预迁…

如何使用Java获取货币符号?

1. 前言 最近做了一个支付相关的需求&#xff0c;要求在收银台页面显示商品的价格时带上货币符号&#xffe5;&#xff0c;类似下图中的格式&#xff1a; 最初我是用的下面这样的代码&#xff1a; System.out.println(Currency.getInstance(Locale.CHINA).getSymbol());本机测…

postgresql_internals-14 学习笔记(一)

梳理一下之前理解不太清楚的知识点&#xff0c;重点内容可能会再拆出来单独研究。 原书链接&#xff1a;Index of / 一、 数据组织 1. pg系统库 template0&#xff1a;用于从逻辑备份还原&#xff0c;或创建不同字符集的数据库&#xff0c;不可以修改template1&#xff1a;真…

[附源码]Python计算机毕业设计SSM基于框架的毕业生就业管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Unity脚本 (1) --- 创建脚本以及挂载脚本的本质,脚本模板的修改

值类型 --- 在栈区中开辟内存空间并直接存储在栈区中&#xff0c;引用类型 --- 在栈区中开辟内存空间存引用&#xff0c;在堆区中开辟内存空间存数据&#xff08;有可能堆区中还要开辟引用&#xff09;&#xff0c;然后将堆区中存储数据的内存空间的地址传给引用接收 什么是脚本…

HTTP 请求走私

目录 0x01 简介 0x02 成因 2.1 Keep-Alive 2.2 Pipeline 2.3 Content-Length 2.4 Transfer-Encoding 0x03 分类 0x04. 攻击 4.1. CL不为0的GET请求 4.2 CL-CL 4.3 CL-TE 4.4 TE-CL 4.5. TE-TE 0x05 防御 参考资料&#xff1a; 0x01 简介 HTTP请求走私是一种干扰…

Mysql优化-全面详解(学习总结---从入门到深化)

Sql性能下降的原因 在程序的运行过程中&#xff0c;我们会发现这样的一个现象&#xff0c;随着程序运行 时间的不断推移以及数据量越来越大&#xff0c;程序响应的时间逐渐变慢&#xff0c; 程序变得卡顿&#xff0c;但最开始的时候并不是这样的&#xff0c;那是什么原因导致 的…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java毕业生回访系统564c4

最近发现近年来越来越多的人开始追求毕设题目的设创、和新颖性。以往的xx管理系统、xx校园系统都过时了。大多数人都不愿意做这类的系统了&#xff0c;确实&#xff0c;从有毕设开始就有人做了。但是很多人又不知道哪些毕设题目才算是新颖、创意。太老土的不想做&#xff0c;创…

RISC-V SiFive U64内核——HPM硬件性能监视器

学习、沉淀、分享&#xff0c;才能有所获~ 文章目录HPM简介性能监控计数器重置行为固定功能性能监控计数器事件可编程性能监控计数器事件选择器寄存器事件选择器编码计数使能寄存器对于性能分析&#xff0c;通常我们会使用Perf工具。而perf中的硬件事件&#xff0c;则需要硬件的…

阿里、腾讯、字节跳动大厂Java岗面试秘籍!(含答案解析)

本文主要是汇集整理了最新的阿里、腾讯、字节跳动大厂面试真题及答案解析&#xff0c;以及面试中被频繁问到的内容&#xff0c;主要作为参考大纲&#xff0c;供大家互相学习。 一、阿里篇&#xff08;27题&#xff09; 1.1.1 如何实现一个高效的单向链表逆序输出&#xff1f;…

当我用ChatGPT中学习CNN卷积神经网络时...

本文节选自本人博客&#xff1a;https://www.blog.zeeland.cn/archives/chatgpt-asoihgoihrx Introduction ChatGPT大火&#xff0c;在这一段时间并没有觉得ChatGPT特别厉害&#xff0c;最多就是一个基于生成式对话的NLP模型罢了&#xff0c;直到我看到了AI扮演Linux虚拟机&am…

[附源码]计算机毕业设计基于web的建设科技项目申报管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【Redis】Redisson 分布式锁主从一致性问题

一、主从一致性问题的产生 Redis 主从集群使用如下&#xff1a; 在主节点进行数据的写操作&#xff1b;在节点进行数据的读操作&#xff1b;主节点向从节点同步数据。 主从一致性问题&#xff1a; 当主节点还没来得及将锁信息同步到从节点时&#xff0c;此时主节点宕机了。然…

【产品分析】高德手机地图产品:未来搜索将从地图开始

未来的搜索从地图开始。今后的所有商务活动都将通过地图展开&#xff0c;使之成为兵家必争之地。要将移动流量变现为真金白银&#xff0c;地图将发挥至关重要的作用。 目前整个中国电子地图市场目前处于应用成熟期。在多年的快速发展和数次大型收购后&#xff0c;各互联网巨头已…

[附源码]计算机毕业设计家庭教育appSpringboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

腾讯在线文档根据单选的内容修改背景颜色

目录 [介绍] [条件格式] [添加条件格式] [选择单元格范围] [条件选择] [格式预览] [管理条件格式] [介绍] 类似我这种场景(见下图),单选选择不同的状态,有时为了一目了然的看清状态,需要给单元格加上不同的背景颜色,但手动使用格式刷比较麻烦,琢磨了下根据单元格选项动态…

【云原生】Nacos 监控手册

Nacos 0.8.0版本完善了监控系统&#xff0c;支持通过暴露metrics数据接入第三方监控系统监控Nacos运行状态&#xff0c;目前支持prometheus、elastic search和influxdb&#xff0c;下面结合prometheus和grafana如何监控Nacos&#xff0c;官网grafana监控页面。 搭建Nacos集群暴…