Django序列化器

article/2025/8/29 14:42:01

一、序列化器作用
1、数据格式转换:
序列化: 对象 -> 字典
反序列化: 字典 -> 对象(OrderedDict)
2、校验参数合法性;
3、保存和修改数据;
二、定义序列化器
通过继承rest_framework.serializers.Serializer来定义序列化器
1、基本定义

class Department(models.Model):"""部门模型类"""name = models.CharField(max_length=20, verbose_name='部门名称')create_date = models.DateField(verbose_name='成立时间')is_delete = models.BooleanField(default=False, verbose_name='是否删除')def __str__(self):return self.nameclass Meta(object):db_table = 'department'class Employee(models.Model):"""员工模型类"""choices_gender = ((0, '男'),(1, '女'),)name = models.CharField(verbose_name='姓名', max_length=20)age = models.IntegerField()gender = models.IntegerField(verbose_name='年龄', default=0, choices=choices_gender)salary = models.DecimalField(verbose_name='工资', max_digits=8, decimal_places=2)comment = models.CharField(verbose_name='备注', max_length=300, null=True, blank=True)hire_date = models.DateField(verbose_name='入职时间', auto_now_add=True)# 关联属性department = models.ForeignKey('Department', verbose_name='所属部门')def __str__(self):return self.nameclass Meta(object):db_table = 'employee'

2.、常用字段类型:

字段字段构造方式
BooleanFieldBooleanField()
NullBooleanFieldNullBooleanField()
CharFieldCharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
EmailFieldEmailField(max_length=None, min_length=None, allow_blank=False)
RegexFieldRegexField(regex, max_length=None, min_length=None, allow_blank=False)
SlugField SlugField(maxlength=50, min_length=None, allow_blank=False) 正则字段,验证正则模式 [a-zA-Z0-9-]+
URLFieldURLField(max_length=200, min_length=None, allow_blank=False)
UUIDFieldUUIDField(format='hex_verbose')
DecimalFieldDecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) max_digits: 最多位数 decimal_palces: 小数点位置
DateTimeField DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)
ChoiceField ChoiceField(choices)
FileFieldFileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
ImageFieldImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
3、选项参数说明

选项参数说明
4、通用选项
通用选项

三、使用序列化器
序列化: 模型对象 -> 字典
1、序列化器的创建

Serializer(instance=None, data=empty, **kwarg)
# instance: 用于序列化时,传入要序列化的模型类对象。
# data: 用于反序列化时,传入字典数据

2、序列化操作
data属性: 获取序列化后得到的字典

from users.models import *
from users.serializers import *dep = Department.objects.get(id=1)
serializer = DepartmentSerializer(dep)
serializer.data
# {'create_date': '2009-01-01', 'name': '研发部', 
#  'is_delete': False, 'id': 1}

3、序列化操作: many=True参数
如果要序列化的是包含多条数据的QuerySet,则需要指定many=True,否则报错:

serializer = DepartmentSerializer(query_set, many=True)
serializer.data
# [OrderedDict([('id', 1), ('name', '研发部'), ('create_date', '2009-01-01'), ('is_delete', False)]), 
# OrderedDict([('id', 2), ('name', '人事部'), ('create_date', '2009-03-01'), ('is_delete', False)])]

四、序列化关联对象
关联对象序列化时,需要指定该如何序列化关联对象
第一种情况: 要序列化的关联对象只有一个,例如:员工对象
最常用的,有如下序列化方式
1、 PrimaryKeyRelatedField
此字段将被序列化为关联对象的主键
必须包含read_only=True或者queryset参数:
包含read_only=True参数时,该字段反序列化时不能使用
包含queryset参数时,将在反序列化,会用作参数合法性校验

department = serializers.PrimaryKeyRelatedField(label='所属部门', read_only=True)
或
department = serializers.PrimaryKeyRelatedField(label='所属部门', queryset=Department.objects.all())

序列化结果:

from users.serializers import *
from users.models import *
employee = Employee.objects.get(id=1)
serializer = EmployeeSerializer(employee)serializer.data
# {'salary': '12000.00', 'comment': None, 'avatar': None, 
# 'department': 1, 'gender': 0, 'age': 28, 'hire_date': '2011-01-01', 'id': 1, 'name': '赵小一'}

2、使用关联对象的序列化器

department = DepartmentSerializer()

序列化结果:

from users.serializers import *
from users.models import *
employee = Employee.objects.get(id=1)
serializer = EmployeeSerializer(employee)serializer.data
# {'avatar': None, 'comment': None, 'hire_date': '2011-01-01', 
#  'salary': '12000.00', 'id': 1, 'name': '赵小一', 'gender': 0, 
#  'department': OrderedDict([('id', 1), ('name', '研发部'), 
#  ('create_date', '2009-01-01'), ('is_delete', False)]), 'age': 28}

第二种情况: 要序列化的关联对象包含多个,例如:想序列化 部门对象时,把部门 关联的员工对象也进行序列化。
配置关联字段类型仍是使用上述介绍的PrimaryKeyRelatedField等方式,只是在声明关联字段时,多补充一个many=True参数

 class DepartmentSerializer(serializers.Serializer):"""部门数据序列化器"""id = serializers.IntegerField(label='ID', read_only=True)name = serializers.CharField(label='部门名称', max_length=20)create_date = serializers.DateField(label='成立时间')is_delete = serializers.BooleanField(label='是否删除', required=False)# 此处仅拿PrimaryKeyRelatedField类型来举例,其他相同employee_set = serializers.PrimaryKeyRelatedField(label='员工', read_only=True, many=True)

序列化结果:

from users.models import *
from users.serializers import *dep = Department.objects.get(id=1)
serializer = DepartmentSerializer(dep)serializer.data
# {'id': 1, 'create_date': '2009-01-01', 'is_delete': False, 
# 'employee_set': [1, 2, 3, 4, 14], 'name': '研发部'}

五、反序列化
1、反序列化基本使用
反序列化: 字典 -> 对象(OrderedDict)
序列化器的创建: 通过data传入字典数据

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

通过is_valid方法校验参数合法性
is_valid()方法:
校验参数是否合法:会根据定义序列化器时,指定的序列化类型和选项参数,进行参数校验,校验通过返回True,否则返回False;
传递参数:is_valid(raise_exception=True);
验证失败时会抛出异常serializers.ValidationError;
REST framework接收到此异常,会向前端返回HTTP 400 Bad Request响应;
errors属性: 获取校验出错信息,字典类型,包含了字段和字段的错误;
validated_data属性: 校验通过得到的对象,类型为OrderedDict;
案例:
案例一:验证不通过

 my_dict = {'create_date':'2018'}serializer = DepartmentSerializer(data=my_dict)serializer.is_valid()      # 验证不通过# Falseserializer.errors# {'create_date': [ErrorDetail(string='Date has wrong format. #   Use one of these formats instead: YYYY[-MM[-DD]].', code='invalid')], # 'name': [ErrorDetail(string='This field is required.', code='required')]}

案例二:验证通过

 my_dict = {'name':'研发部33', 'create_date':'2018-1-1'}serializer = DepartmentSerializer(data=my_dict)serializer.is_valid()  # 验证通过# Trueserializer.validated_data# OrderedDict([('name', '研发部33'), #     ('create_date', datetime.date(2018, 1, 1))])

六、参数校验的几种方式
1、validate_<field_name>方法:对<field_name>字段进行验证,例:

class DepartmentSerializer(serializers.Serializer):"""部门数据序列化器"""...def validate_name(self, value):# 校验部门名称if not re.match('^[A-Za-z\u4e00-\u9fa5]+$', value):raise ValidationError('部门名称只能为中文或英语字母')return value

2、validate方法:对多个字段进行比较校验,例:

 # 模型: users/models.pyclass User(models.Model):password = models.CharField(max_length=30)password2 = models.CharField(max_length=30)# 序列化器: users/serializer.pyclass UserSerializer(serializers.Serializer):password = serializers.CharField(max_length=30)password2 = serializers.CharField(max_length=30)def validate(self, attrs):# 校验两次输入的密码是否正确password = attrs['password']password2 = attrs['password2']if password != password2:raise serializers.ValidationError('两个输入的密码不一样')return attrs

3、validators字段选项:在序列化器字段中添加validators选项参数进行校验,例:
使用 UniqueValidator(字段唯一) 校验字段不能重复

class DepartmentSerializer(serializers.Serializer):"""部门数据序列化器"""...name = serializers.CharField(label='部门名称', max_length=20,validators=[UniqueValidator(queryset=Department.objects.all())])

七、保存或修改数据
1、Serializer类的三个方法
save()方法: 新增或修改
create(self, validated_data)方法: 新增数据
update(self, instance, validated_data)方法: 修改数据
2、Serializer类的save()方法: 新增或修改一条数据

DepartmentSerializer(instance=None, data=my_dict)

创建Serializer对象时,如果没有传递instance实例
调用Serializer对象的save()方法时会执行create()新增数据

DepartmentSerializer(instance=department, data=my_dict)

创建Serializer对象时,传递了instance实例
调用Serializer对象的save()方法时会执行update()修改数据:

department = Department.objects.get(id=1)
my_dict = {'name': '研发部xx', 'create_date': '2018-1-1'}
s = DepartmentSerializer(instance=department, data=my_dict)    
s.save()        # 修改数据

3、required=True参数
(1)当修改数据时,序列化器默认要求传递所有required=True的字段,否则is_valid验证不通过
(2)可以通过设置partial=True允许只修改部分字段,如下:

s = DepartmentSerializer(comment, data={'create_date': '2017-1-1'}, partial=True)

4、重写 Serializer类的create()和update()方法

 class DepartmentSerializer(serializers.Serializer):"""部门序列化器"""...def create(self, validated_data):"""保存部门"""return Department.objects.create(**validated_data)def update(self, instance, validated_data):"""修改部门:instance为要修改的部门对象,validated_data为用户发请求提交过来的数据,已经通过校验"""instance.name = validated_data.get('name', instance.name)instance.create_date = validated_data.get('create_date', instance.create_date)instance.save()   # 修改数据库数据return instance

八、模型序列化器
DRF提供了模型类序列化器: ModelSerializer
作用: 简化对应django模型类的序列化器的定义
ModelSerializer与常规的Serializer相同,但提供了:
基于模型类自动生成一系列字段;
基于模型类自动为Serializer生成validators;
包含默认的create()和update()的实现;
1、 定义

class DepartmentSerializer(serializers.ModelSerializer):"""部门序列化器"""class Meta:model = Department    # 关联的模型类对象fields = '__all__'    # 表示包含模型类中所有字段

在python console 交互环境中,查看生成的序列化器

>>> s = DepartmentSerializer()
>>> s
DepartmentSerializer():id = IntegerField(label='ID', read_only=True)name = CharField(label='部门名称', max_length=20)create_date = DateField(label='成立时间')is_delete = BooleanField(label='是否删除', required=False)

2、属性说明

  1. fields属性:可以指定为__all__,也可以写明具体哪些字段
  2. exclude属性:排除字段
  3. 新增模型中不存在的字段(或修改已存在字段)
  4. 指明只读字段
    可以通过 read_only_fields 指明只读字段,即仅用于序列化输出,在反序列化时不进行校验和保存
    5)添加额外参数: extra_kwargs属性
class DepartmentSerializer(serializers.ModelSerializer):employee_set = EmployeeSerializer() # 新增模型类不存在字段class Meta:model = Department# fields = '__all__'        exclude = ('is_delete',)read_only_fields = ('id',)  # 部门id,成立时间extra_kwargs = {'name': {'required': True, 'min_length': 2, 'max_length': 20}}

结果如下:

DepartmentSerializer():id = IntegerField(label='ID', read_only=True)name = CharField(max_length=20, min_length=2, required=True)create_date = DateField(read_only=True)employee_set = EmployeeSerializer():id = IntegerField(label='ID', read_only=True)name = CharField(label='姓名', max_length=20)age = IntegerField(label='年龄')gender = ChoiceField(choices=((0, '男'), (1, '女')), default=0, label='性别')salary = DecimalField(decimal_places=2, label='工资', max_digits=8)comment = CharField(label='备注', max_length=300, required=False)hire_date = DateField(label='入职时间', required=False)department = PrimaryKeyRelatedField(help_text='所属部门', label='所属部门', read_only=True)

http://chatgpt.dhexx.cn/article/rBYOQUV9.shtml

相关文章

Qt知识点梳理 —— 自定义数据结构序列化与反序列化

文章目录 定义 Qt中序列化与反序列化 序列化&#xff1a; 反序列化&#xff1a; 自定义数据结构序列化与反序列化 项目结构 数据结构信息 执行效果 项目源码 开发环境 定义 序列化&#xff1a;将对象或数据结构转换为二进制序列 反序列化&#xff1a;二进制序列转换…

序列化作用

没有implements Serializable&#xff0c;你就不能通过rmi(包括ejb)提供远程调用。 serialization 允许你将实现了Serializable接口的对象转换为字节序列&#xff0c;这些字节序列可以被完全存储以备以后重新生成原来的对象。 serialization不但可以在本机做&#…

PHP反序列化

定义 序列化&#xff08;串行化&#xff09;&#xff1a;是将变量转换为可保存或传输的字符串的过程&#xff1b; 反序列化&#xff08;反串行化&#xff09;&#xff1a;就是在适当的时候把这个字符串再转化成原来的变量使用&#xff1b; 这两个过程结合起来&#xff0c;可以轻…

Spark序列化简介

参考文章&#xff1a;Spark序列化 spark之kryo 序列化 Spark序列化入门 1. 什么是序列化和序列化? 序列化是什么 序列化的作用就是可以将对象的内容变成二进制, 存入文件中保存反序列化指的是将保存下来的二进制对象数据恢复成对象 序列化对对象的要求 对象必须实现 Serial…

谈谈序列化的作用

文章目录 1. 写在前面2. 问题阐述3. 解释3.1 一些不够完整的解释3.2 一种完整的解释3.2.1 去地址3.2.2 节省空间 4. 小节参考链接 1. 写在前面 我们应该都用过各种序列化&#xff08;serialization&#xff09;的方法&#xff08;如Python中的pickle.dumps&#xff09;&#x…

Java 之 Serializable 序列化和反序列化的概念,作用的通俗易懂的解释

遇到这个 Java Serializable 序列化这个接口&#xff0c;我们可能会有如下的问题 a&#xff0c;什么叫序列化和反序列化 b&#xff0c;作用。为啥要实现这个 Serializable 接口&#xff0c;也就是为啥要序列化 c&#xff0c;serialVersionUID 这个的值到底是在怎么设置的&#…

cas 原理分析

CAS 原理分析 1、了解java中锁的类型 1.1 悲观锁(Pessimistic Lock) 顾名思义&#xff0c;就是很悲观&#xff0c;假定会发生并发冲突&#xff0c;屏蔽一切可能违反数据完整性的操作&#xff0c;每次去拿数据的时候都认为别人会修改&#xff0c;所以每次在拿数据的时候都会上…

JAVA中的CAS算法

java 中的线程之间的栈空间是相互独立&#xff0c;堆空间是共享的 V&#xff1a;内存值就是主内存中i值 A&#xff1a;预估值(期望值)就是子线程拿到主内存的值&#xff08;读取到高速缓存中的值&#xff09; B&#xff1a;更新值是子线程拿到i值后,修改i的值 假设有两个线程…

面试:CAS算法原理

1、什么是CAS&#xff1f; CAS&#xff1a;Compare and Swap&#xff0c;即比较再交换。 jdk5增加了并发包java.util.concurrent.*&#xff0c;其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证同步的&#x…

CAS原理详解

CAS介绍 CAS全称是Compare And Swap&#xff0c;它的实现和它的字面意思一样&#xff0c;先比较后交换&#xff0c;它是CPU硬件层面的一种指令&#xff0c;从CPU层面能保证"比较并更新"这一段操作的原子性。 与synchronized关键字比较不同是synchronized是一种悲观锁…

CAS算法与ABA问题

锁是用来做并发最简单的方式&#xff0c;当然代价也是最高的。 独占锁是一种悲观锁&#xff0c;synchronized就是一种独占锁&#xff1b;它假设最坏的情况&#xff0c;并且只有在确保其它线程不会造成干扰的情况下执行&#xff0c;会导致其它所有需要锁的线程挂起直到持有锁的…

CAS算法-实现原理

目录 CAS是什么&#xff1f; CAS解决了什么问题&#xff1f; CAS存在什么问题&#xff1f; CAS有哪些应用场景&#xff1f; cas的实现 最后 CAS是什么&#xff1f; CAS的全称为Compare and swap 比较并交换。CAS又经常被称为乐观锁&#xff0c;主要的三个变量&#xff0c;内存值…

并发策略-CAS算法

对于并发控制而言&#xff0c;我们平时用的锁&#xff08;synchronized&#xff0c;Lock&#xff09;是一种悲观的策略。它总是假设每一次临界区操作会产生冲突&#xff0c;因此&#xff0c;必须对每次操作都小心翼翼。如果多个线程同时访问临界区资源&#xff0c;就宁可牺牲性…

深入理解CAS算法原理

转载自 深入理解CAS算法原理 1、什么是CAS&#xff1f; CAS&#xff1a;Compare and Swap&#xff0c;即比较再交换。 jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证…

CAS操作原理

1、什么是CAS&#xff1f; CAS&#xff1a;Compare and Swap&#xff0c;即比较再交换。 jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证同步的&#xff0c;这是一…

CAS原理

一、CAS 1.1 CAS概述和作用 CAS的全称是&#xff1a; Compare And Swap(比较相同再交换)。是现代CPU广泛支持的一种对内存中的共享数据进行操作的一种特殊指令。 CAS的作用&#xff1a;CAS可以将比较和交换转换为原子操作&#xff0c;这个原子操作直接由CPU保证。 CAS可以保证…

CAS算法详解

CAS算法 1、CAS概念&#xff1a; CAS是CompareAndSwap的缩写&#xff0c;中文意思是&#xff1a;比较并替换。当要进行CAS操作时&#xff0c;先比较内存地址和原来预期的 地址比较&#xff0c;如果相同&#xff0c;表示这块内存地址没有被修改&#xff0c;可以用新地址替换&…

CAS的原理和使用

CAS 文章目录 CAS一、学习CAS首先了解原子类&#xff1f;1. 何为原子类 二、 CAS是什么1. CAS是什么2. CAS原理3. 使用CAS实例代码4. CAS属于硬件级别保证5. 源码分析 三、CAS底层原理&#xff1f;如果知道&#xff0c;谈谈你对UnSafe的理解1. UnSafe2. 我们知道i线程不安全的&…

对cas算法的理解

cas算法主要关心3个值&#xff1a;内存值V&#xff0c;预期值A&#xff0c;要更新的新值B 如下图所示&#xff1a; 注&#xff1a;t1&#xff0c;t2线程是同时更新同一变量56的值 因为t1和t2线程都同时去访问同一变量56&#xff0c;所以他们会把主内存的值完全拷贝一份到自己…

CAS原理分析

CAS的英文为Compare and Swap 翻译为比较并交换。 CAS加volatile关键字是实现并发包的基石。没有CAS就不会有并发包&#xff0c;synchronized是一种独占锁、悲观锁&#xff0c;java.util.concurrent中借助了CAS指令实现了一种区别于synchronized的一种乐观锁。 什么是乐观锁与…