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随机生成一个6位的验证码代码分享
Mar 24 Python
简单介绍Python中利用生成器实现的并发编程
May 04 Python
python函数形参用法实例分析
Aug 04 Python
基于python内置函数与匿名函数详解
Jan 09 Python
python正则表达式及使用正则表达式的例子
Jan 22 Python
Python使用matplotlib和pandas实现的画图操作【经典示例】
Jun 13 Python
PyCharm 设置SciView工具窗口的方法
Jan 15 Python
python函数与方法的区别总结
Jun 23 Python
python plotly画柱状图代码实例
Dec 13 Python
python开发飞机大战游戏
Jul 15 Python
python数据可视化使用pyfinance分析证券收益示例详解
Nov 20 Python
Python可视化神器pyecharts之绘制箱形图
Jul 07 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 __autoload函数(自动载入类文件)的使用方法
2012/02/04 PHP
奇怪的PHP引用效率问题分析
2012/03/23 PHP
PHP转换文件夹下所有文件编码的实现代码
2013/06/06 PHP
ThinkPHP惯例配置文件详解
2014/07/14 PHP
PHP实现的简单sha1加密功能示例
2017/08/27 PHP
PHP连接及操作PostgreSQL数据库的方法详解
2019/01/30 PHP
PHP使用PDO创建MySQL数据库、表及插入多条数据操作示例
2019/05/30 PHP
Save a File Using a File Save Dialog Box
2007/06/18 Javascript
jQuery textarea的长度进行验证
2009/05/06 Javascript
利用JQuery动画制作滑动菜单项效果实现步骤及代码
2013/02/07 Javascript
基于nodejs+express4.X实现文件下载的实例代码
2017/07/13 NodeJs
Vue DevTools调试工具的使用
2017/12/05 Javascript
vuex 的简单使用
2018/03/22 Javascript
vue实现折线图 可按时间查询
2020/08/21 Javascript
Python 抓取动态网页内容方案详解
2014/12/25 Python
在Heroku云平台上部署Python的Django框架的教程
2015/04/20 Python
Python AES加密实例解析
2018/01/18 Python
Python数据分析之双色球基于线性回归算法预测下期中奖结果示例
2018/02/08 Python
python定时按日期备份MySQL数据并压缩
2019/04/19 Python
Pyqt5 基本界面组件之inputDialog的使用
2019/06/25 Python
基于Modernizr 让网站进行优雅降级的分析
2013/04/21 HTML / CSS
使用canvas绘制贝塞尔曲线
2014/12/17 HTML / CSS
基于HTML5新特性Mutation Observer实现编辑器的撤销和回退操作
2016/01/11 HTML / CSS
Nip + Fab官网:英国美容品牌
2019/08/26 全球购物
世界上最大的铁人三项商店:Tri UK
2020/11/04 全球购物
HSRP的含义以及如何工作
2014/09/10 面试题
大四学年自我鉴定
2013/11/13 职场文书
计算机通信工程专业毕业生推荐信
2013/12/24 职场文书
报社实习生自荐信
2014/01/24 职场文书
求职简历自我评价范例
2014/03/12 职场文书
写给同学的新学期寄语
2015/02/27 职场文书
2015应届毕业生求职信范文
2015/03/20 职场文书
2015年卫生院健康教育工作总结
2015/07/24 职场文书
golang实现浏览器导出excel文件功能
2022/03/25 Golang
vue如何实现关闭对话框后刷新列表
2022/04/08 Vue.js
javascript进阶篇深拷贝实现的四种方式
2022/07/07 Javascript