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 修改文件指定行的方法
May 15 Python
Python实现获取某天是某个月中的第几周
Feb 11 Python
浅谈Python类里的__init__方法函数,Python类的构造函数
Dec 10 Python
用pandas按列合并两个文件的实例
Apr 12 Python
Django+JS 实现点击头像即可更改头像的方法示例
Dec 26 Python
Python同步遍历多个列表的示例
Feb 19 Python
tensor和numpy的互相转换的实现示例
Aug 02 Python
python的mysql数据库建立表与插入数据操作示例
Sep 30 Python
Python发送手机动态验证码代码实例
Feb 28 Python
Python 给下载文件显示进度条和下载时间的实现
Apr 02 Python
浅析Python 条件控制语句
Jul 15 Python
python BeautifulSoup库的安装与使用
Dec 17 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函数spl_autoload_register()用法和__autoload()介绍
2012/02/04 PHP
PHP中使用TCPDF生成PDF文档实例
2014/07/01 PHP
PDO防注入原理分析以及注意事项
2015/02/25 PHP
ThinkPHP3.2.2的插件控制器功能
2015/03/05 PHP
深入理解PHP中的Streams工具
2015/07/03 PHP
laravel5实现微信第三方登录功能
2018/12/06 PHP
深入浅析安装PhpStorm并激活的步骤详解
2020/09/17 PHP
JS 实现Table相同行的单元格自动合并示例代码
2013/08/27 Javascript
jquery检测input checked 控件是否被选中的方法
2014/03/26 Javascript
javascript实现仿IE顶部的可关闭警告条
2015/05/05 Javascript
javascript学习笔记之函数定义
2015/06/25 Javascript
Jquery ajax 同步阻塞引起的UI线程阻塞问题
2015/11/17 Javascript
详解Node.js包的工程目录与NPM包管理器的使用
2016/02/16 Javascript
jQuery.deferred对象使用详解
2016/03/18 Javascript
javascript关于继承解析
2016/05/10 Javascript
vue模板语法-插值详解
2017/03/06 Javascript
js打开word文档预览操作示例【不是下载】
2019/05/23 Javascript
[05:02][DOTA2]DOTA进化论 第一期
2013/09/27 DOTA
[01:35:13]DOTA2-DPC中国联赛 正赛 DLG vs PHOENIX BO3 第一场 1月18日
2021/03/11 DOTA
对python制作自己的数据集实例讲解
2018/12/12 Python
在Python中关于使用os模块遍历目录的实现方法
2019/01/03 Python
Python分割训练集和测试集的方法示例
2019/09/19 Python
深入浅析python的第三方库pandas
2020/02/13 Python
将数据集制作成VOC数据集格式的实例
2020/02/17 Python
用python批量移动文件
2021/01/14 Python
Nisbets爱尔兰:英国最大的厨房和餐饮设备供应商
2019/01/26 全球购物
大学毕业生自荐书怎么写?
2014/01/06 职场文书
经济贸易系毕业生求职信
2014/05/31 职场文书
2014迎国庆演讲稿
2014/09/19 职场文书
2014年大学生党员自我评议
2014/09/22 职场文书
个人政风行风自查自纠报告
2014/10/21 职场文书
习近平在党的群众路线教育实践活动总结大会上的讲话
2014/10/21 职场文书
实习单位意见
2015/06/04 职场文书
教你怎么用Python处理excel实现自动化办公
2021/04/30 Python
linux下安装redis图文详细步骤
2021/12/04 Redis
python 使用pandas读取csv文件的方法
2022/12/24 Python