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正则表达式匹配HTML页面编码
Apr 08 Python
Python对列表中的各项进行关联详解
Aug 15 Python
Python实现基于二叉树存储结构的堆排序算法示例
Dec 08 Python
Python 实现在文件中的每一行添加一个逗号
Apr 29 Python
Python multiprocessing多进程原理与应用示例
Feb 28 Python
Python安装Flask环境及简单应用示例
May 03 Python
pyqt5移动鼠标显示坐标的方法
Jun 21 Python
Python Threading 线程/互斥锁/死锁/GIL锁
Jul 21 Python
Django使用unittest模块进行单元测试过程解析
Aug 02 Python
Python上下文管理器全实例详解
Nov 12 Python
详解从Django Allauth中进行登录改造小结
Dec 18 Python
pytorch SENet实现案例
Jun 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
PHP脚本的10个技巧(1)
2006/10/09 PHP
PHP 反向排序和随机排序代码
2010/06/30 PHP
PHP的imageTtfText()函数深入详解
2021/03/03 PHP
AJAX分页的代码(后台asp.net)
2011/02/14 Javascript
Nodejs中读取中文文件编码问题、发送邮件和定时任务实例
2015/01/01 NodeJs
简述AngularJS相关的一些编程思想
2015/06/23 Javascript
基于jQuery实现在线选座之高铁版
2015/08/24 Javascript
JavaScript的ExtJS框架中表格的编写教程
2016/05/21 Javascript
Ionic实现页面下拉刷新(ion-refresher)功能代码
2016/06/03 Javascript
JS简单设置下拉选择框默认值的方法
2016/08/20 Javascript
node.js将MongoDB数据同步到MySQL的步骤
2017/12/10 Javascript
搭建vue开发环境
2018/07/19 Javascript
js根据需要计算数组中重复出现某个元素的个数
2019/01/18 Javascript
vue发送websocket请求和http post请求的实例代码
2019/07/11 Javascript
Net微信网页开发 使用微信JS-SDK获取当前地理位置过程详解
2019/08/26 Javascript
微信小程序自定义模态弹窗组件详解
2019/12/24 Javascript
微信小程序实现时间戳格式转换
2020/07/20 Javascript
js仿淘宝放大镜效果
2020/12/28 Javascript
Python自动重试HTTP连接装饰器
2015/04/28 Python
Python实现的彩票机选器实例
2015/06/17 Python
基于python(urlparse)模板的使用方法总结
2017/10/13 Python
疯狂上涨的Python 开发者应从2.x还是3.x着手?
2017/11/16 Python
Python+OpenCV图片局部区域像素值处理改进版详解
2019/01/23 Python
对Python定时任务的启动和停止方法详解
2019/02/19 Python
使用Python快乐学数学Github万星神器Manim简介
2019/08/07 Python
Python循环实现n的全排列功能
2019/09/16 Python
用Python写一个自动木马程序
2019/09/17 Python
Python3.7安装keras和TensorFlow的教程图解
2020/06/18 Python
HTML5中的websocket实现直播功能
2018/05/21 HTML / CSS
印尼最大的婴儿用品购物网站:Orami
2017/09/28 全球购物
人力资源行政经理自我评价
2013/10/23 职场文书
2014年招商工作总结
2014/11/22 职场文书
2016年度先进班组事迹材料
2016/03/01 职场文书
2016年感恩教师节活动总结
2016/04/01 职场文书
开网店计划分析
2019/07/30 职场文书
Go gorilla/sessions库安装使用
2022/08/14 Golang