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中操作字典之setdefault()方法的使用
May 21 Python
Python模块搜索概念介绍及模块安装方法介绍
Jun 03 Python
Python用zip函数同时遍历多个迭代器示例详解
Nov 14 Python
python爬虫中get和post方法介绍以及cookie作用
Feb 08 Python
python实现汽车管理系统
Nov 30 Python
python隐藏终端执行cmd命令的方法
Jun 24 Python
用Python实现BP神经网络(附代码)
Jul 10 Python
Python产生一个数值范围内的不重复的随机数的实现方法
Aug 21 Python
python实现网站微信登录的示例代码
Sep 18 Python
如何基于python实现画不同品种的樱花树
Jan 03 Python
Pytorch 扩展Tensor维度、压缩Tensor维度的方法
Sep 09 Python
Golang Web 框架Iris安装部署
Aug 14 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+.htaccess实现全站静态HTML文件GZIP压缩传输(一)
2007/02/15 PHP
深入分析php中接口与抽象类的区别
2013/06/08 PHP
深入解析PHP 5.3.x 的strtotime() 时区设定 警告信息修复
2013/08/05 PHP
php共享内存段示例分享
2014/01/20 PHP
排序算法之PHP版快速排序、冒泡排序
2014/04/09 PHP
Thinkphp中volist标签mod控制一定记录的换行BUG解决方法
2014/11/04 PHP
基于linnux+phantomjs实现生成图片格式的网页快照
2015/04/15 PHP
php使用变量动态创建类的对象用法示例
2017/02/06 PHP
Thinkphp5框架使用validate实现验证功能的方法
2019/08/27 PHP
用javascript实现页面打印的三种方法
2007/03/05 Javascript
学习ExtJS Panel常用方法
2009/10/07 Javascript
基于JQuery的模拟苹果桌面Dock效果(稳定版)
2012/10/15 Javascript
JavaScript字符串String和Array操作的有趣方法
2012/12/18 Javascript
动态创建script在IE中缓存js文件时导致编码的解决方法
2014/05/04 Javascript
JavaScript学习小结(一)——JavaScript入门基础
2015/09/02 Javascript
jquery解析XML及获取XML节点名称的实现代码
2016/05/18 Javascript
js删除数组元素、清空数组的简单方法(必看)
2016/07/27 Javascript
原生js实现验证码功能
2017/03/16 Javascript
JavaScript for循环 if判断语句(学习笔记)
2017/10/11 Javascript
jQuery进阶实践之利用最优雅的方式如何写ajax请求
2017/12/20 jQuery
Vue Socket.io源码解读
2018/02/07 Javascript
基于vue.js组件实现分页效果
2018/12/29 Javascript
深入理解JavaScript 箭头函数
2019/05/30 Javascript
vue 遮罩层阻止默认滚动事件操作
2020/07/28 Javascript
[03:13]DOTA2-DPC中国联赛1月25日Recap集锦
2021/03/11 DOTA
python基础知识小结之集合
2015/11/25 Python
详解Python的Twisted框架中reactor事件管理器的用法
2016/05/25 Python
python版微信跳一跳游戏辅助
2018/01/11 Python
Python调用接口合并Excel表代码实例
2020/03/31 Python
python 解决mysql where in 对列表(list,,array)问题
2020/06/06 Python
Python爬虫过程解析之多线程获取小米应用商店数据
2020/11/14 Python
Python大批量搜索引擎图像爬虫工具详解
2020/11/16 Python
自主招生自荐信
2013/12/08 职场文书
教师群众路线剖析材料
2014/09/29 职场文书
党员教师四风问题整改措施思想汇报
2014/10/08 职场文书
工程项目经理岗位职责
2015/02/02 职场文书