django Serializer序列化使用方法详解


Posted in Python onOctober 16, 2018

Serializer序列化器

定义Serializer

1. 定义方法

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

例如,我们已有了一个数据库模型类BookInfo

class BookInfo(models.Model):
  btitle = models.CharField(max_length=20, verbose_name='名称')
  bpub_date = models.DateField(verbose_name='发布日期', null=True)
  bread = models.IntegerField(default=0, verbose_name='阅读量')
  bcomment = models.IntegerField(default=0, verbose_name='评论量')
  image = models.ImageField(upload_to='booktest', verbose_name='图片', null=True)

我们想为这个模型类提供一个序列化器,可以定义如下:

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

注意:serializer不是只能为数据库模型类定义,也可以为非数据库模型类的数据定义。serializer是独立于数据库之外的存在。

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) 'hex_verbose' 如"5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 2) 'hex' 如 "5ce0e9a55ffa654bcee01238041fb31a" 3)'int' - 如: "123456789012312313134124512351145145114" 4)'urn' 如: "urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a"
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. 创建Serializer对象

定义好Serializer类后,就可以创建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 基本使用

1) 先查询出一个图书对象

from booktest.models import BookInfo
book = BookInfo.objects.get(id=2)

2) 构造序列化器对象

from booktest.serializers import BookInfoSerializer
serializer = BookInfoSerializer(book)

3)获取序列化数据

通过data属性可以获取序列化后的数据

serializer.data
# {'id': 2, 'btitle': '天龙八部', 'bpub_date': '1986-07-24', 'bread': 36, 'bcomment': 40, 'image': None}

4)如果要被序列化的是包含多条数据的查询集QuerySet,可以通过添加many=True参数补充说明

book_qs = BookInfo.objects.all()
serializer = BookInfoSerializer(book_qs, many=True)
serializer.data
# [OrderedDict([('id', 2), ('btitle', '天龙八部'), ('bpub_date', '1986-07-24'), ('bread', 36), ('bcomment', 40), ('image', N]), OrderedDict([('id', 3), ('btitle', '笑傲江湖'), ('bpub_date', '1995-12-24'), ('bread', 20), ('bcomment', 80), ('image'ne)]), OrderedDict([('id', 4), ('btitle', '雪山飞狐'), ('bpub_date', '1987-11-11'), ('bread', 58), ('bcomment', 24), ('ima None)]), OrderedDict([('id', 5), ('btitle', '西游记'), ('bpub_date', '1988-01-01'), ('bread', 10), ('bcomment', 10), ('im', 'booktest/xiyouji.png')])]

2 关联对象嵌套序列化

如果需要序列化的数据中包含有其他关联对象,则对关联对象数据的序列化需要指明。

例如,在定义英雄数据的序列化器时,外键hbook(即所属的图书)字段如何序列化?

我们先定义HeroInfoSerialzier除外键字段外的其他部分

class HeroInfoSerializer(serializers.Serializer):
  """英雄数据序列化器"""
  GENDER_CHOICES = (
    (0, 'male'),
    (1, 'female')
  )
  id = serializers.IntegerField(label='ID', read_only=True)
  hname = serializers.CharField(label='名字', max_length=20)
  hgender = serializers.ChoiceField(choices=GENDER_CHOICES, label='性别', required=False)
  hcomment = serializers.CharField(label='描述信息', max_length=200, required=False, allow_null=True)

对于关联字段,可以采用以下几种方式:

1) PrimaryKeyRelatedField

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

hbook = serializers.PrimaryKeyRelatedField(label='图书', read_only=True)
或
hbook = serializers.PrimaryKeyRelatedField(label='图书', queryset=BookInfo.objects.all())

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

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

使用效果:

from booktest.serializers import HeroInfoSerializer
from booktest.models import HeroInfo
hero = HeroInfo.objects.get(id=6)
serializer = HeroInfoSerializer(hero)
serializer.data
# {'id': 6, 'hname': '乔峰', 'hgender': 1, 'hcomment': '降龙十八掌', 'hbook': 2}

2) StringRelatedField

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

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

使用效果

{'id': 6, 'hname': '乔峰', 'hgender': 1, 'hcomment': '降龙十八掌', 'hbook': '天龙八部'}

3)HyperlinkedRelatedField

此字段将被序列化为获取关联对象数据的接口链接

hbook = serializers.HyperlinkedRelatedField(label='图书', read_only=True, view_name='books-detail')

必须指明view_name参数,以便DRF根据视图名称寻找路由,进而拼接成完整URL。

使用效果

{'id': 6, 'hname': '乔峰', 'hgender': 1, 'hcomment': '降龙十八掌', 'hbook': 'http://127.0.0.1:8000/books/2/'}

我们暂时还没有定义视图,此方式不再演示。

4)SlugRelatedField

此字段将被序列化为关联对象的指定字段数据

hbook = serializers.SlugRelatedField(label='图书', read_only=True, slug_field='bpub_date')

slug_field指明使用关联对象的哪个字段

使用效果

{'id': 6, 'hname': '乔峰', 'hgender': 1, 'hcomment': '降龙十八掌', 'hbook': datetime.date(1986, 7, 24)}

5)使用关联对象的序列化器

hbook = BookInfoSerializer()

使用效果

{'id': 6, 'hname': '乔峰', 'hgender': 1, 'hcomment': '降龙十八掌', 'hbook': OrderedDict([('id', 2), ('btitle', '天龙八部')te', '1986-07-24'), ('bread', 36), ('bcomment', 40), ('image', None)])}

6) 重写to_representation方法

序列化器的每个字段实际都是由该字段类型的to_representation方法决定格式的,可以通过重写该方法来决定格式。

注意,to_representations方法不仅局限在控制关联对象格式上,适用于各个序列化器字段类型。

自定义一个新的关联字段:

class BookRelateField(serializers.RelatedField):
  """自定义用于处理图书的字段"""
  def to_representation(self, value):
    return 'Book: %d %s' % (value.id, value.btitle)

指明hbook为BookRelateField类型

hbook = BookRelateField(read_only=True)

使用效果

{'id': 6, 'hname': '乔峰', 'hgender': 1, 'hcomment': '降龙十八掌', 'hbook': 'Book: 2 天龙八部'}

many参数

如果关联的对象数据不是只有一个,而是包含多个数据,如想序列化图书BookInfo数据,每个BookInfo对象关联的英雄HeroInfo对象可能有多个,此时关联字段类型的指明仍可使用上述几种方式,只是在声明关联字段时,多补充一个many=True参数即可。

此处仅拿PrimaryKeyRelatedField类型来举例,其他相同。

在BookInfoSerializer中添加关联字段:

class BookInfoSerializer(serializers.Serializer):
  """图书数据序列化器"""
  id = serializers.IntegerField(label='ID', read_only=True)
  btitle = serializers.CharField(label='名称', max_length=20)
  bpub_date = serializers.DateField(label='发布日期', required=False)
  bread = serializers.IntegerField(label='阅读量', required=False)
  bcomment = serializers.IntegerField(label='评论量', required=False)
  image = serializers.ImageField(label='图片', required=False)
  heroinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True) # 新增

使用效果:

from booktest.serializers import BookInfoSerializer
from booktest.models import BookInfo
book = BookInfo.objects.get(id=2)
serializer = BookInfoSerializer(book)
serializer.data
# {'id': 2, 'btitle': '天龙八部', 'bpub_date': '1986-07-24', 'bread': 36, 'bcomment': 40, 'image': Non

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现截屏的函数
Jul 26 Python
Python爬虫之xlml解析库(全面了解)
Aug 08 Python
深入理解Python中的*重复运算符
Oct 28 Python
Python 通配符删除文件的实例
Apr 24 Python
django js实现部分页面刷新的示例代码
May 28 Python
pygame游戏之旅 添加游戏暂停功能
Nov 21 Python
解决Python 命令行执行脚本时,提示导入的包找不到的问题
Jan 19 Python
Python 使用Numpy对矩阵进行转置的方法
Jan 28 Python
详解用python实现基本的学生管理系统(文件存储版)(python3)
Apr 25 Python
python 实现的发送邮件模板【普通邮件、带附件、带图片邮件】
Jul 06 Python
python循环嵌套的多种使用方法解析
Nov 29 Python
Python如何将将模块分割成多个文件
Aug 04 Python
为什么str(float)在Python 3中比Python 2返回更多的数字
Oct 16 #Python
对python添加模块路径的三种方法总结
Oct 16 #Python
Python中的CSV文件使用"with"语句的方式详解
Oct 16 #Python
详解django的serializer序列化model几种方法
Oct 16 #Python
Python调用C++,通过Pybind11制作Python接口
Oct 16 #Python
Python之inspect模块实现获取加载模块路径的方法
Oct 16 #Python
django 将model转换为字典的方法示例
Oct 16 #Python
You might like
逐步提升php框架的性能
2008/01/10 PHP
php printf输出格式使用说明
2010/12/05 PHP
dhtmlxTree目录树增加右键菜单以及拖拽排序的实现方法
2013/04/26 PHP
浅析Mysql 数据回滚错误的解决方法
2013/08/05 PHP
PHP面向对象程序设计高级特性详解(接口,继承,抽象类,析构,克隆等)
2016/12/02 PHP
Laravel框架实现的使用smtp发送邮件功能示例
2019/03/12 PHP
Apache+PHP+MySQL搭建PHP开发环境图文教程
2020/08/06 PHP
点击文章内容处弹出页面代码
2009/10/01 Javascript
JS+XML 省份和城市之间的联动实现代码
2009/10/14 Javascript
单击复制文字兼容各浏览器的完美解决方案
2013/07/04 Javascript
vue 国际化 vue-i18n 双语言 语言包
2018/06/07 Javascript
基于Layui自定义模块的使用方法详解
2019/09/14 Javascript
javascript实现视频弹幕效果(两个版本)
2019/11/28 Javascript
原生JS实现留言板
2020/03/26 Javascript
Javascript实现贪吃蛇小游戏(含详细注释)
2020/10/23 Javascript
Python 多核并行计算的示例代码
2017/11/07 Python
selenium处理元素定位点击无效问题
2019/06/12 Python
Python简单处理坐标排序问题示例
2019/07/11 Python
Python操作远程服务器 paramiko模块详细介绍
2019/08/07 Python
浅谈python的elementtree模块处理中文注意事项
2020/03/06 Python
Python新手学习raise用法
2020/06/03 Python
Selenium+BeautifulSoup+json获取Script标签内的json数据
2020/12/07 Python
TensorFlow低版本代码自动升级为1.0版本
2021/02/20 Python
美国流行背包品牌:JanSport(杰斯伯)
2018/03/02 全球购物
商务邀请函范文
2014/01/14 职场文书
男方父母婚礼答谢词
2014/01/25 职场文书
初中生自我鉴定
2014/02/04 职场文书
如何写自我评价?自我评价写什么好?
2014/03/14 职场文书
委托公证书
2014/04/08 职场文书
生产助理岗位职责
2014/06/18 职场文书
竞选班干部演讲稿600字
2014/08/20 职场文书
小学向国旗敬礼活动方案
2014/09/27 职场文书
党支部书记岗位职责
2015/02/15 职场文书
财务经理岗位职责范本
2015/04/08 职场文书
爱国主义教育基地观后感
2015/06/18 职场文书
浅谈Python响应式类库RxPy
2021/06/14 Python