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解析网页源代码中的115网盘链接实例
Sep 30 Python
pymongo为mongodb数据库添加索引的方法
May 11 Python
Python第三方库的安装方法总结
Jun 06 Python
python交互式图形编程实例(三)
Nov 17 Python
Python多继承顺序实例分析
May 26 Python
python使用Plotly绘图工具绘制气泡图
Apr 01 Python
详解pyppeteer(python版puppeteer)基本使用
Jun 12 Python
Django 接收Post请求数据,并保存到数据库的实现方法
Jul 12 Python
超简单的Python HTTP服务
Jul 22 Python
Python中常见的数制转换有哪些
May 27 Python
Keras 中Leaky ReLU等高级激活函数的用法
Jul 05 Python
详解Python中__new__方法的作用
Mar 31 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
IIS+fastcgi下PHP运行超时问题的解决办法详解
2013/06/20 PHP
php addslashes 利用递归实现使用反斜线引用字符串
2013/08/05 PHP
Mac OS下配置PHP+MySql环境
2015/02/25 PHP
PHP使用逆波兰式计算工资的方法
2015/07/29 PHP
PHP实现批量重命名某个文件夹下所有文件的方法
2017/09/04 PHP
浅谈PHP接入(第三方登录)QQ登录 OAuth2.0 过程中遇到的坑
2017/10/13 PHP
PHP单例模式数据库连接类与页面静态化实现方法
2019/03/20 PHP
laravel Model 执行事务的实现
2019/10/10 PHP
Javascript常用运算符(Operators)-javascript基础教程
2007/12/14 Javascript
JQuery 动态扩展对象之另类视角
2010/05/25 Javascript
javascript是怎么继承的介绍
2012/01/05 Javascript
JavaScript中用于四舍五入的Math.round()方法讲解
2015/06/15 Javascript
AngularJS入门之动画
2016/07/27 Javascript
总结JavaScript的正则与其他语言的不同之处
2016/08/25 Javascript
js控制div层的叠加简单方法
2016/10/15 Javascript
JS html时钟制作代码分享
2017/03/03 Javascript
Vue自定义指令写法与个人理解
2019/02/09 Javascript
在VUE style中使用data中的变量的方法
2020/06/19 Javascript
Vue实现手机计算器
2020/08/17 Javascript
Vue常用API、高级API的相关总结
2021/02/02 Vue.js
[08:04]TI4西雅图DOTA2前线报道 海涛探访各路人马
2014/07/09 DOTA
[48:41]VP vs VG Supermajor小组赛 B组胜者组决赛 BO3 第二场 6.2
2018/06/03 DOTA
Python中使用Beautiful Soup库的超详细教程
2015/04/30 Python
疯狂上涨的Python 开发者应从2.x还是3.x着手?
2017/11/16 Python
Python中利用xpath解析HTML的方法
2018/05/14 Python
如何使用python进行pdf文件分割
2019/11/11 Python
html5中地理位置定位api接口开发应用小结
2013/01/04 HTML / CSS
海外淘书首选:AbeBooks
2017/07/31 全球购物
Sunglasses Shop瑞典:欧洲领先的太阳镜网上商店
2018/04/22 全球购物
大码女装:Ulla Popken
2019/08/06 全球购物
开会迟到检讨书
2014/02/03 职场文书
2014学年自我鉴定
2014/02/23 职场文书
大型演出策划方案
2014/05/28 职场文书
2015年度党风廉政建设工作情况汇报
2015/01/02 职场文书
解决Navicat for MySQL 连接 MySQL 报2005错误的问题
2021/05/29 MySQL
Python实现随机生成迷宫并自动寻路
2021/06/13 Python