Django框架序列化与反序列化操作详解


Posted in Python onNovember 01, 2019

本文实例讲述了Django框架序列化与反序列化操作。分享给大家供大家参考,具体如下:

Serializer类

1.定义:

Django REST framework中的Serializer使用类来定义,须继承rest_framework.serializers.Serializer。

例:

class BookInfoSerializer(serializers.Serializer):
 """图书数据序列化器"""
 id = serializers.IntegerField(label='ID', read_only=True)
 name = serializers.CharField(label='名称', max_length=20)
 pub_date = serializers.DateField(label='发布日期', required=False)
 readcount = serializers.IntegerField(label='阅读量', required=False)
 commentcount = serializers.IntegerField(label='评论量', required=False)
 image = serializers.ImageField(label='图片', required=False)

2.字段与选项:

常用字段类型:

字段 字段构造方式
BooleanField BooleanField()
NullBooleanField NullBooleanField()
CharField CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
EmailField EmailField(max_length=None, min_length=None, allow_blank=False)
RegexField RegexField(regex, max_length=None, min_length=None, allow_blank=False)
SlugField SlugField(maxlength=50, min_length=None, allow_blank=False) 正则字段,验证正则模式 [a-zA-Z0-9-]+
URLField URLField(max_length=200, min_length=None, allow_blank=False)
UUIDField UUIDField(format=‘hex_verbose') format: 1)
IPAddressField IPAddressField(protocol=‘both', unpack_ipv4=False, **options)
IntegerField IntegerField(max_value=None, min_value=None)
FloatField FloatField(max_value=None, min_value=None)
DecimalField DecimalField(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)
DateField DateField(format=api_settings.DATE_FORMAT, input_formats=None)
TimeField TimeField(format=api_settings.TIME_FORMAT, input_formats=None)
DurationField DurationField()
ChoiceField ChoiceField(choices) choices与Django的用法相同
MultipleChoiceField MultipleChoiceField(choices)
FileField FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
ImageField ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
ListField ListField(child=, min_length=None, max_length=None)
DictField DictField(child=)

选项参数:

参数名称 作用
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页面时,显示的字段帮助提示信息

3.Serialize对象:

构造方法:

Serializer(instance, data, **kwarg)

(1)用于序列化时,将模型类对象传入instance参数
(2)用于反序列化时,将要被反序列化的数据传入data参数
(3)除了instance和data参数外,在构造Serializer对象时,还可通过context参数额外 添加数据。

例:

serializer = AccountSerializer(account, context={'request': request})

通过context参数附加的数据,可以通过Serializer对象的context属性获取。

序列化

1.基本使用:

(1)查询对象:
例:

from book.models import BookInfo
book = BookInfo.objects.get(id=4) # 单个对象
books = BookInfo.objects.all() # 多个对象

(2)构造序列化对象:

from book.serializers import BookInfoSerializer
serializer = BookInfoSerializer(book) # 单个对象
serializers = BookInfoSerializer(books,many=True) # 多个对象需要添加many参数

(3)获取序列化数据:

serializer.data

2.外键嵌套使用:

(1)PrimaryKeyRelatedField:

此字段将被序列化为关联对象的主键。

book = serializers.PrimaryKeyRelatedField(label='图书',read_only=True)

或者

book=serializers.PrimaryKeyRelatedField(label='图书',queryset=BookInfo.objects.all())

指明字段时需要包含read_only=True或者queryset参数:

  • 包含read_only=True参数时,该字段将不能用作反序列化使用
  • 包含queryset参数时,将被用作反序列化时参数校验使用

结果:

{'id': 10, 'book': 3, 'description': '独孤九剑', 'gender': 1, 'name': '令狐冲'}

(2)StringRelateField:

此字段将被序列化为关联对象的字符串表示方式(即__str__方法的返回值)

book = serializers.StringRelatedField(label='图书')

结果:

{'description': '独孤九剑', 'name': '令狐冲', 'gender': 1, 'book': '笑傲江湖', 'id': 10}

(3)使用关联对象的序列化器:

book = BookInfoSerializer()

结果:

{'book': OrderedDict([('id', 3), ('name', '笑傲江湖'), ('pub_date', '1995-12-24'),  ('readcount', 28), ('commentcount',  ('image', None)]), 'gender': 1, 'name': '令狐冲',  'description': '独孤九剑', 'id': 10}

反序列化

1.验证:

(1)字段验证:

from book.serializers import BookInfoSerializer
data = {'pub_date':'2010-1-1','name':'python高级'}
serializer = BookInfoSerializer(data=data)
serializer.is_valid() # 验证成功返回True,失败返回False

is_valid()方法还可以在验证失败时抛出异常serializers.ValidationError,可以通过传递raise_exception=True参数开启,REST framework接收到此异常,会向前端返回HTTP 400 Bad Request响应。

(2)字段选项:

可在序列化器中设置字段的属性,来限制数据,对数据进行验证。

例:

属性 描述
max_length 字符串的最大长度(char)
min_length 字符串的最小长度
max_value 最大值(int)
min_value 最小值
required 表明该字段在反序列化时必须输入,默认True
default 默认值

(3)单个字段验证:

当我们的类型和选项都满足条件之后,我们需要对单个字段的值进行校验,我们在序 列化器中实现方法以 validate_ 开头以字段名结尾的函数

格式:

def validate_字段名(self,value):
...
return value

例:

def validate_readcount(self,value):
  if value < 0:
   raise serializers.ValidationError('阅读量不能为负数')
  # 验证完成之后,需要将 value返回
  return value

(4)多的字段验证:

对多个字段进行校验的时候,我们在序列器中实现

格式:

def validate(self,attrs)
...
  return attrs

例:

def validate(self, data):
  # attrs = data
  # params --> 序列化器data --> attrs
  """
  data = {
   'name':'python',
   'pub_date':'2000-1-1',
   'readcount':10,
   'commentcount':100
  }
  """
  readcount = data.get('readcount')
  # if readcount<0:
  #  raise serializers.ValidationError()
  commentcount = data.get('commentcount')
  if readcount<commentcount:
   raise serializers.ValidationError('评论量不能大于阅读量')
  #校验完成之后,必须要将数据返回回去
  return data

(5)自定义验证:

在字段中添加validators选项参数,也可以补充验证行为

例:

name=serializers.CharField(max_length=20,validators=[custom_validate)]
def custom_validate(self):
if self == 'admin':
raise serializers.ValidationError('admin不可用')
 raise serializers.ValidationError('我就是来捣乱的')

2.保存:

如果在验证成功后,想要基于validated_data完成数据对象的创建,可以通过实现create()和update()两个方法来实现。

(1)create方法:

def create(self, validated_data):
  # validated_data 验证之后的数据
  # params(前端提交的数据) --> data(序列器接受的数据) --> attrs(多个字段 校验) --> validated_data(校验之后)
  # 如果前段提交的数据 经过序列化器的验证之后完全满足需求,则
  # validated_data = params
  """
   validated_data:
  data = {
   'name':'python',
   'pub_date':'2000-1-1',
   'readcount':10000,
   'commentcount':100
  }
  """
  # book = BookInfo()
  # book.save()
  book = BookInfo.objects.create(**validated_data)
  # 需要将创建的对象返回
  return book
( return BookInfo.objects.create(**validated_data)也可)

(2)update方法:

def update(self, instance, validated_data):
"""更新,instance为要更新的对象实例"""
 instance.name = validated_data.get('name', instance.name)
 instance.pub_date = validated_data.get('pub_date', instance.pub_date)
 instance.readcount = validated_data.get('readcount', instance.readcount)
...
instance.save()
 return instance

实现了上述两个方法后,在反序列化数据的时候,就可以通过save()方法返回一个数据对象实例了

例:

book = serializer.save()

如果创建序列化器对象的时候,没有传递instance实例,则调用save()方法的时候,create()被调用,相反,如果传递了instance实例,则调用save()方法的时候,update()被调用。

两点说明:

1) 在对序列化器进行save()保存时,可以额外传递数据,这些数据可以在create()和update()中的validated_data参数获取到

serializer.save(owner=request.user)

2)默认序列化器必须传递所有required的字段,否则会抛出验证异常。但是我们可以使用partial参数来允许部分字段更新

serializer = BookInfoSerializer(instance=book, data={'pub_date': '2999-1-1'}, partial=True)

模型类序列化器BookModelSerializer

1.定义:

例:

创建一个BookInfoSerializer

class BookInfoSerializer(serializers.ModelSerializer):

 class Meta:
  model = BookInfo
  fields = '__all__'

参数 描述
model 指明参照哪个模型类
fields 指明为模型类的哪些字段生成

2.指定字段:

(1)全部字段:

fields = '__all__'

(2)排除字段:

exclude = ['xxx', 'xxxx'...]

(3)指定字段:

fields = ['xxx', 'xxxx'...]

(4)只读字段:

read_only_fields = ['xxx', 'xxxx'...]

3.添加额外参数:

可以使用extra_kwargs参数为ModelSerializer添加或修改原有的选项参数

例:

class BookInfoSerializer(serializers.ModelSerializer):
class Meta:
model = BookInfo
 fields = ('id','name', 'readcount', 'commentcount')
 read_only_fields = ('id', 'readcount', 'commentcount')
 extra_kwargs = {
  'readcount': {'min_value': 0, 'required': True},
  'commentcount': {'max_value': 0, 'required': True},
 }

希望本文所述对大家基于Django框架的Python程序设计有所帮助。

Python 相关文章推荐
Python基于DES算法加密解密实例
Jun 03 Python
深入学习python的yield和generator
Mar 10 Python
使用Python的Django框架结合jQuery实现AJAX购物车页面
Apr 11 Python
对pandas中apply函数的用法详解
Apr 10 Python
python3第三方爬虫库BeautifulSoup4安装教程
Jun 19 Python
python 正确保留多位小数的实例
Jul 16 Python
python3中os.path模块下常用的用法总结【推荐】
Sep 16 Python
python 使用socket传输图片视频等文件的实现方式
Aug 07 Python
利用Python校准本地时间的方法教程
Oct 31 Python
Pytorch保存模型用于测试和用于继续训练的区别详解
Jan 10 Python
使用Python来做一个屏幕录制工具的操作代码
Jan 18 Python
解决Jupyter无法导入已安装的 module问题
Apr 17 Python
redis数据库及与python交互用法简单示例
Nov 01 #Python
python验证码图片处理(二值化)
Nov 01 #Python
使用matlab或python将txt文件转为excel表格
Nov 01 #Python
python 图片二值化处理(处理后为纯黑白的图片)
Nov 01 #Python
Python网络编程之使用TCP方式传输文件操作示例
Nov 01 #Python
wxpython布局的实现方法
Nov 01 #Python
Python高级编程之消息队列(Queue)与进程池(Pool)实例详解
Nov 01 #Python
You might like
点评山进PR-D3L三波段收音机
2021/03/02 无线电
供参考的 php 学习提高路线分享
2011/10/23 PHP
php中使用接口实现工厂设计模式的代码
2012/06/17 PHP
win7+apache+php+mysql环境配置操作详解
2013/06/10 PHP
PHP curl 获取响应的状态码的方法
2014/01/13 PHP
ThinkPHP文件上传实例教程
2014/08/22 PHP
用 Composer构建自己的 PHP 框架之设计 MVC
2014/10/30 PHP
ThinkPHP查询语句与关联查询用法实例
2014/11/01 PHP
PHP children()函数讲解
2019/02/03 PHP
PHP的cookie与session原理及用法详解
2019/09/27 PHP
tp5.1 框架数据库高级查询技巧实例总结
2020/05/25 PHP
LazyLoad 延迟加载(按需加载)
2010/05/31 Javascript
js中数组排序sort方法的原理分析
2014/11/20 Javascript
Javascript实现飞动广告效果的方法
2015/05/25 Javascript
JavaScript中函数表达式和函数声明及函数声明与函数表达式的不同
2015/11/15 Javascript
JavaScript常用正则验证函数实例小结【年龄,数字,Email,手机,URL,日期等】
2017/01/23 Javascript
详解Vue使用命令行搭建单页面应用
2017/05/24 Javascript
基于JS脚本语言的基础语法详解
2017/07/22 Javascript
js+canvas实现滑动拼图验证码功能
2018/03/26 Javascript
ES6 Promise对象的含义和基本用法分析
2019/06/14 Javascript
node 版本切换的实现
2020/02/02 Javascript
基于Element封装一个表格组件tableList的使用方法
2020/06/29 Javascript
pygame学习笔记(1):矩形、圆型画图实例
2015/04/15 Python
使用PDB简单调试Python程序简明指南
2015/04/25 Python
利用matplotlib+numpy绘制多种绘图的方法实例
2017/05/03 Python
python web框架中实现原生分页
2019/09/08 Python
如何基于python生成list的所有的子集
2019/11/11 Python
Python中如何添加自定义模块
2020/06/09 Python
浅谈keras中的后端backend及其相关函数(K.prod,K.cast)
2020/06/29 Python
python自动提取文本中的时间(包含中文日期)
2020/08/31 Python
UI自动化定位常用实现方法代码示例
2020/10/27 Python
资产评估专业大学生求职信
2013/09/29 职场文书
电脑教师的教学自我评价
2013/11/26 职场文书
医生党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
2015年全民国防教育日活动总结
2015/03/23 职场文书
彻底解决MySQL使用中文乱码的方法
2022/01/22 MySQL