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 20 Python
Python中字典的基础知识归纳小结
Aug 19 Python
Python argv用法详解
Jan 08 Python
再谈Python中的字符串与字符编码(推荐)
Dec 14 Python
使用python生成杨辉三角形的示例代码
Aug 29 Python
python 将list转成字符串,中间用符号分隔的方法
Oct 23 Python
Python关于excel和shp的使用在matplotlib
Jan 03 Python
Django Channels 实现点对点实时聊天和消息推送功能
Jul 17 Python
Django框架ORM数据库操作实例详解
Nov 07 Python
Django多进程滚动日志问题解决方案
Dec 17 Python
Python selenium使用autoIT上传附件过程详解
May 26 Python
python math模块的基本使用教程
Jan 16 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
WordPress开发中自定义菜单的相关PHP函数使用简介
2016/01/05 PHP
PHP htmlspecialchars() 函数实例代码及用法大全
2018/09/18 PHP
Laravel 中创建 Zip 压缩文件并提供下载的实现方法
2019/04/02 PHP
Laravel 模型使用软删除-左连接查询-表起别名示例
2019/10/24 PHP
php生成随机数/生成随机字符串的方法小结【5种方法】
2020/05/27 PHP
TNC vs BOOM BO3 第一场2.13
2021/03/10 DOTA
jquery实现的鼠标下拉滚动置顶效果
2014/07/24 Javascript
javascript设计模式之中介者模式Mediator
2014/12/30 Javascript
JavaScript使用Max函数返回两个数字中较大数的方法
2015/04/06 Javascript
在JavaScript中使用开平方根的sqrt()方法
2015/06/15 Javascript
JQuery实现左右滚动菜单特效
2015/09/28 Javascript
javascript函数自动执行常用方法汇总
2016/03/28 Javascript
异步加载JS、CSS代码(推荐)
2016/06/15 Javascript
通过一个简单的例子学会vuex与模块化
2017/11/22 Javascript
利用JQUERY实现多个AJAX请求等待的实例
2017/12/14 jQuery
通过fastclick源码分析彻底解决tap“点透”
2017/12/24 Javascript
用npm安装vue和vue-cli,并使用webpack创建项目的方法
2018/09/28 Javascript
vue-router路由模式详解(小结)
2019/08/26 Javascript
关于vue.js中实现方法内某些代码延时执行
2019/11/14 Javascript
原生js实现自定义消息提示框
2020/11/19 Javascript
用Python制作简单的钢琴程序的教程
2015/04/01 Python
调试Python程序代码的几种方法总结
2015/04/28 Python
Caffe均值文件mean.binaryproto转mean.npy的方法
2018/07/09 Python
Python学习笔记之lambda表达式用法详解
2019/08/08 Python
python/Matplotlib绘制复变函数图像教程
2019/11/21 Python
如何基于python操作json文件获取内容
2019/12/24 Python
基于FME使用Python过程图解
2020/05/13 Python
Python classmethod装饰器原理及用法解析
2020/10/17 Python
植村秀加拿大官网:Shu Uemura加拿大
2019/09/03 全球购物
莫斯科制造商的廉价皮大衣:Fursk
2020/06/09 全球购物
化学系大学生自荐信范文
2014/03/01 职场文书
明信片寄语大全
2014/04/08 职场文书
人事局接收函
2015/01/31 职场文书
商场圣诞节活动总结
2015/05/06 职场文书
我爱我班主题班会
2015/08/13 职场文书
python3实现无权最短路径的方法
2021/05/12 Python