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 文件与目录操作
Dec 24 Python
python 排列组合之itertools
Mar 20 Python
Python+PIL实现支付宝AR红包
Feb 09 Python
用Python下载一个网页保存为本地的HTML文件实例
May 21 Python
Python 字符串与数字输出方法
Jul 16 Python
python flask几分钟实现web服务的例子
Jul 26 Python
解决Mac下使用python的坑
Aug 13 Python
Python 使用元类type创建类对象常见应用详解
Oct 17 Python
Python+OpenCV 实现图片无损旋转90°且无黑边
Dec 12 Python
套娃式文件夹如何通过Python批量处理
Aug 23 Python
python中doctest库实例用法
Dec 31 Python
pycharm安装深度学习pytorch的d2l包失败问题解决
Mar 25 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&amp;&amp;mysql)五
2006/10/09 PHP
解析百度搜索结果link?url=参数分析 (全)
2012/10/09 PHP
解析PHP的session过期设置
2013/06/29 PHP
php出现内存位置访问无效错误问题解决方法
2014/08/16 PHP
Yii框架应用组件用法实例分析
2020/05/15 PHP
文本框中,回车键触发事件的js代码[多浏览器兼容]
2010/06/07 Javascript
javascript动画之圆形运动,环绕鼠标运动作小球
2010/07/20 Javascript
表单JS弹出填写提示效果代码
2011/04/16 Javascript
用js替换除数字与逗号以外的所有字符的代码
2014/06/07 Javascript
node.js中的fs.writeSync方法使用说明
2014/12/15 Javascript
js获取json元素数量的方法
2015/01/27 Javascript
javascript移动开发中touch触摸事件详解
2016/03/18 Javascript
利用transition实现文字上下抖动的效果
2017/01/21 Javascript
vue使用watch 观察路由变化,重新获取内容
2017/03/08 Javascript
js实现首屏延迟加载实现方法 js实现多屏单张图片延迟加载效果
2017/07/17 Javascript
jQuery选择器特殊字符与属性空格问题
2017/08/14 jQuery
Vue中封装input组件的实例详解
2017/10/17 Javascript
浅析node Async异步处理模块用例分析及常用方法介绍
2017/11/17 Javascript
详解JS中统计函数执行次数与执行时间
2018/09/04 Javascript
jQuery.parseJSON()函数详解
2019/02/28 jQuery
详解django模板与vue.js冲突问题
2019/07/07 Javascript
Vue在chrome44偶现点击子元素事件无法冒泡的解决方法
2019/12/15 Javascript
python多线程抓取天涯帖子内容示例
2014/04/03 Python
python复制文件的方法实例详解
2015/05/22 Python
在Django的视图中使用form对象的方法
2015/07/18 Python
Python使用微信SDK实现的微信支付功能示例
2017/06/30 Python
python实现协同过滤推荐算法完整代码示例
2017/12/15 Python
CSS3字体效果的设置方法小结
2016/06/13 HTML / CSS
html5+css3之动画在webapp中的应用
2014/11/21 HTML / CSS
中国最大的团购网站:聚划算
2016/09/21 全球购物
如何写出好的Java代码
2014/04/25 面试题
给面试官的感谢信
2014/02/01 职场文书
教育学习自我评价
2014/02/03 职场文书
五四青年节演讲稿
2014/05/26 职场文书
《酸的和甜的》教学反思
2016/02/18 职场文书
浅谈Redis主从复制以及主从复制原理
2021/05/29 Redis