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 文件操作技巧(File operation) 实例代码分析
Aug 11 Python
详解python中的json的基本使用方法
Dec 21 Python
python 连接各类主流数据库的实例代码
Jan 30 Python
Python图片转换成矩阵,矩阵数据转换成图片的实例
Jul 02 Python
python3利用venv配置虚拟环境及过程中的小问题小结
Aug 01 Python
Python实现的括号匹配判断功能示例
Aug 25 Python
python+splinter实现12306网站刷票并自动购票流程
Sep 25 Python
Django如何开发简单的查询接口详解
May 17 Python
PyQt5响应回车事件的方法
Jun 25 Python
基于python使用tibco ems代码实例
Dec 20 Python
Django模型验证器介绍与源码分析
Sep 08 Python
pytorch交叉熵损失函数的weight参数的使用
May 24 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
一个用于MySQL的PHP XML类
2006/10/09 PHP
在线短消息收发的程序,不用数据库
2006/10/09 PHP
php获得当前的脚本网址
2007/12/10 PHP
php计算年龄精准到年月日
2015/11/17 PHP
PHP+MySql实现一个简单的留言板
2020/07/19 PHP
JavaScript代码简单实现求杨辉三角给定行的最大值
2013/10/29 Javascript
用js读、写、删除Cookie代码续篇
2014/12/03 Javascript
Javascript中的匿名函数与封装介绍
2015/03/15 Javascript
jquery实现从数组移除指定的值
2015/06/24 Javascript
轻松学习jQuery插件EasyUI EasyUI创建CRUD应用
2015/11/30 Javascript
基于JavaScript实现复选框的全选和取消全选
2017/02/09 Javascript
vue-router路由简单案例介绍
2017/02/21 Javascript
ES6学习教程之对象的扩展详解
2017/05/02 Javascript
javascript实现Java中的Map对象功能的实例详解
2017/08/21 Javascript
Vuejs2 + Webpack框架里,模拟下载的实例讲解
2018/09/05 Javascript
vue读取本地的excel文件并显示在网页上方法示例
2019/05/29 Javascript
vue项目中将element-ui table表格写成组件的实现代码
2019/06/12 Javascript
js+springMVC 提交数组数据到后台的实例
2019/09/21 Javascript
Js on及addEventListener原理用法区别解析
2020/07/11 Javascript
python实现360皮肤按钮控件示例
2014/02/21 Python
非递归的输出1-N的全排列实例(推荐)
2017/04/11 Python
python3.5 tkinter实现页面跳转
2018/01/30 Python
python smtplib发送带附件邮件小程序
2018/05/22 Python
Python文件读写保存操作的示例代码
2018/09/14 Python
Python3爬虫教程之利用Python实现发送天气预报邮件
2018/12/16 Python
python实现蒙特卡罗方法教程
2019/01/28 Python
python实现生成Word、docx文件的方法分析
2019/08/30 Python
如何在windows下安装Pycham2020软件(方法步骤详解)
2020/05/03 Python
马来西亚网上购物平台:ezbuy
2018/02/13 全球购物
美国和加拿大计算机和电子产品购物网站:TigerDirect.com
2019/09/13 全球购物
大学生找工作求职信
2014/07/09 职场文书
党的群众路线教育实践活动个人剖析材料
2014/10/07 职场文书
酒店采购员岗位职责
2015/04/03 职场文书
导游词之上海豫园
2019/10/24 职场文书
JavaScript阻止事件冒泡的方法
2021/12/06 Javascript
redis 解决库存并发问题实现数量控制
2022/04/08 Redis