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 中的divmod数字处理函数浅析
Oct 17 Python
深入理解Python中的super()方法
Nov 20 Python
Python编程求质数实例代码
Jan 31 Python
在Python中实现替换字符串中的子串的示例
Oct 31 Python
详解Python连接MySQL数据库的多种方式
Apr 16 Python
python爬虫神器Pyppeteer入门及使用
Jul 13 Python
使用Python实现画一个中国地图
Nov 23 Python
Python+numpy实现矩阵的行列扩展方式
Nov 29 Python
如何将你的应用迁移到Python3的三个步骤
Dec 22 Python
手把手教你从PyCharm安装到激活(最新激活码),亲测有效可激活至2089年
Nov 25 Python
python openssl模块安装及用法
Dec 06 Python
对象析构函数__del__在Python中何时使用
Mar 22 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 上一篇,下一篇文章实现代码与原理说明
2010/05/09 PHP
ThinkPHP3.1基础知识快速入门
2014/06/19 PHP
PhpStorm terminal无法输入命令的解决方法
2016/10/09 PHP
php数值转换时间及时间转换数值用法示例
2017/05/18 PHP
使用PHP+MySql+Ajax+jQuery实现省市区三级联动功能示例
2017/09/15 PHP
PHP解析url并得到url参数方法总结
2018/10/11 PHP
JS不间断向上滚动效果代码
2013/12/25 Javascript
jQuery基于图层模仿五星星评价功能的方法
2015/05/07 Javascript
TypeError document.getElementById(...) is null错误原因
2015/05/18 Javascript
JS实现的在线调色板实例(附demo源码下载)
2016/03/01 Javascript
设置点击文本框或图片弹出日历控件的实现代码
2016/05/12 Javascript
javascript数组对象常用api函数小结(连接,插入,删除,反转,排序等)
2016/09/20 Javascript
vue2实现搜索结果中的搜索关键字高亮的代码
2018/08/29 Javascript
基于vue.js实现分页查询功能
2018/12/29 Javascript
three.js实现炫酷的全景3D重力感应
2018/12/30 Javascript
el-input 标签中密码的显示和隐藏功能的实例代码
2019/07/19 Javascript
基于ts的动态接口数据配置的详解
2019/12/18 Javascript
Vue 中获取当前时间并实时刷新的实现代码
2020/05/12 Javascript
JS判断数组四种实现方法详解
2020/06/29 Javascript
JavaScript如何实现防止重复的网络请求的示例
2021/01/28 Javascript
浅谈Python实现贪心算法与活动安排问题
2017/12/19 Python
Python参数解析模块sys、getopt、argparse使用与对比分析
2019/04/02 Python
利用python开发app实战的方法
2019/07/09 Python
Pycharm 文件更改目录后,执行路径未更新的解决方法
2019/07/19 Python
vscode配置anaconda3的方法步骤
2020/08/08 Python
python中turtle库的简单使用教程
2020/11/11 Python
No module named ‘win32gui‘ 的解决方法(踩坑之旅)
2021/02/18 Python
HTML5中的新元素介绍
2008/10/17 HTML / CSS
ECHT官方网站:男女健身服
2020/02/14 全球购物
介绍一下.net和Java的特点和区别
2012/09/26 面试题
高中生学习的自我评价
2013/12/14 职场文书
暑期政治学习心得体会
2014/09/02 职场文书
2015年重阳节慰问信
2015/03/23 职场文书
幼儿园毕业典礼家长致辞
2015/07/29 职场文书
PYTHON InceptionV3模型的复现详解
2022/05/06 Python
nginx实现多geoserver服务的负载均衡
2022/05/15 Servers