django restframework serializer 增加自定义字段操作


Posted in Python onJuly 15, 2020

在使用django restframework serializer 序列化在django中定义的model时,有时候我们需要额外在serializer中增加一些model中没有的字段。有两种方法实现这个目的。

假设现在有一个Animal模型,其中有name, type, country字段,country为外键。我们在序列化Animal时,需要额外增加外键country的area信息。

方法一修改数据库,利用model 这里就不多解释,主要来说第二种,不修改django的model,直接使用SerializerMethodField(method_name=None)字段。

class AnimalSerializer(serializers.ModelSerializer):
 country_area = serializers.SerializerMethodField()

 class Meta:
  model = Animal
  fields = ('id', 'name', 'type','country','country_area')

 def get_country_area(self, obj):
  return obj.country.area

SerializerMethodFiel是一个read-only字段

当不指定其method_name时,默认为get_field_name

如果使用ModelSerializer并指定字段时,要包含此时定义的字段

补充知识:django restframework Serializer field

SerializerMethodField

这是一个只读字段。它通过调用它所连接的序列化类的方法来获得它的值。它可用于将任何类型的数据添加到对象的序列化表示中。

签名: SerializerMethodField(method_name=None)

method_name - 要调用序列化对象的方法的名称。如果不包含,则默认为 get_<field_name>.

由 method_name 参数引用的序列化方法应该接受一个参数(除了 self),这是要序列化的对象。它应该返回你想要包含在对象的序列化表示中的任何内容。例如:

场景介绍:一个用户往往对应多个角色,而角色字段并不在UserProfile表中,这就需要我们新增角色字段到user序列化中

from .models import UserProfile
from .models import UserRole

class UserProfileSerializer(serializers.ModelSerializer):
 """
 show list serializer
 """
 role = serializers.SerializerMethodField()

 class Meta:
  model = UserProfile
  # fields = "__all__"
  fields = ["id", "username","role", "account", "really_name", "department", "tel_phone",
     "create_time", "email", "last_time", "creator"]

 def get_role(self,obj):
  user_id = obj.id
  roles = [i.role.name for i in UserRole.objects.filter(user_id=user_id)]
  roles = ",".join(roles)
  return roles

相反的场景:我们提交的表单数据存在于多表中(因为表中含有多对多字段),如何验证所有字段,并保存完整的数据到各表中。

刚开始的思路在ModelSerializer中新增未定义字段,然后发现这并不可行。我也犯了SerializerMethodField的错误,但随后去读了serializer的源码,以及了解serializer的顺序,就知道SerializerMethodField仅用于list方法。

问题的突破点到底在哪里呢,在drf serializer 官方文档中就有一个知识点,serializer.save(**kwargs),kwargs数据被绑定在serializer.validated_data对象上,当create或update的时候就会被添加进数据库,相当于validated_data.update(kwargs)

实际源码不是这样子,但也就是这么个意思。

重写Serializer create,update方法

from rest_framework.utils import model_meta

 def create(self, validated_data):
  field= validated_data.pop('field_name')
  validated_data = validated_data
  instance = Model.objects.create(**validated_data)
  # ...外键表的操作
  return instance

 def update(self, instance, validated_data):
  field= validated_data.pop('field_name')
  info = model_meta.get_field_info(instance)

  for attr, value in validated_data.items():
   if attr in info.relations and info.relations[attr].to_many:
    field = getattr(instance, attr)
    field.set(value)
   else:
    setattr(instance, attr, value)
  instance.save()
  # ...
  return instance

以上这篇django restframework serializer 增加自定义字段操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python保存MongoDB上的文件到本地的方法
Mar 16 Python
Python常用算法学习基础教程
Apr 13 Python
python处理xml文件的方法小结
May 02 Python
浅谈flask截获所有访问及before/after_request修饰器
Jan 18 Python
python同时遍历数组的索引和值的实例
Nov 15 Python
12个Python程序员面试必备问题与答案(小结)
Jun 24 Python
Python+pyplot绘制带文本标注的柱状图方法
Jul 08 Python
Python学习笔记之Break和Continue用法分析
Aug 14 Python
Django url,从一个页面调到另个页面的方法
Aug 21 Python
python实现拼接图片
Mar 23 Python
使用PyQt的QLabel组件实现选定目标框功能的方法示例
May 19 Python
pyqt5 textEdit、lineEdit操作的示例代码
Aug 12 Python
浅谈django不使用restframework自定义接口与使用的区别
Jul 15 #Python
浅析Python 条件控制语句
Jul 15 #Python
python中如何设置代码自动提示
Jul 15 #Python
PyTorch实现重写/改写Dataset并载入Dataloader
Jul 14 #Python
python实现将中文日期转换为数字日期
Jul 14 #Python
Python实时监控网站浏览记录实现过程详解
Jul 14 #Python
python3 中时间戳、时间、日期的转换和加减操作
Jul 14 #Python
You might like
详解PHP中cookie和session的区别及cookie和session用法小结
2016/06/12 PHP
在云虚拟主机部署thinkphp5项目的步骤详解
2017/12/21 PHP
PHP多进程通信-消息队列使用
2019/03/08 PHP
Yii框架操作cookie与session的方法实例详解
2019/09/04 PHP
从javascript语言本身谈项目实战
2006/12/27 Javascript
JavaScript高级程序设计 客户端存储学习笔记
2011/09/10 Javascript
仿百度的关键词匹配搜索示例
2013/09/25 Javascript
IE中鼠标经过option触发mouseout的解决方法
2015/01/29 Javascript
jQuery实现获取绑定自定义事件元素的方法
2015/12/02 Javascript
jQuery siblings()用法实例详解
2016/04/26 Javascript
基于jquery实现三级下拉菜单
2016/05/10 Javascript
Ext JS动态加载JavaScript创建窗体的方法
2016/06/23 Javascript
基于Javascript实现文件实时加载进度的方法
2016/10/12 Javascript
vue2.0+webpack环境的构造过程
2016/11/08 Javascript
vue-cli项目如何使用vue-resource获取本地的json数据(模拟服务端返回数据)
2017/08/04 Javascript
nodejs实现简单的gulp打包
2017/12/21 NodeJs
Angular事件之不同组件间传递数据的方法
2018/11/15 Javascript
element-ui table span-method(行合并)的实现代码
2018/12/20 Javascript
通过vue刷新左侧菜单栏操作
2020/08/06 Javascript
深入解析Python编程中super关键字的用法
2016/06/24 Python
Python 出现错误TypeError: ‘NoneType’ object is not iterable解决办法
2017/01/12 Python
Python将文本去空格并保存到txt文件中的实例
2018/07/24 Python
python游戏开发之视频转彩色字符动画
2019/04/26 Python
python实现批量nii文件转换为png图像
2019/07/18 Python
如何把python项目部署到linux服务器
2020/08/26 Python
英国领先的亚洲旅游专家:Wendy Wu Tours
2018/01/21 全球购物
Nike挪威官网:Nike.com (NO)
2018/11/26 全球购物
墨尔本复古时尚品牌:Dangerfield
2018/12/12 全球购物
Watchshop德国:欧洲在线手表No.1
2019/06/20 全球购物
香港士多网上超级市场:Ztore
2021/01/09 全球购物
《中华少年》教学反思
2014/02/15 职场文书
《狮子和兔子》教学反思
2014/03/02 职场文书
廉洁校园实施方案
2014/05/25 职场文书
安全员岗位职责范本
2015/04/11 职场文书
读书笔记怎么写
2015/07/01 职场文书
python使用XPath解析数据爬取起点小说网数据
2021/04/22 Python