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计算最小优先级队列代码分享
Dec 18 Python
python使用scrapy解析js示例
Jan 23 Python
python每隔N秒运行指定函数的方法
Mar 16 Python
Python批量重命名同一文件夹下文件的方法
May 25 Python
利用python修改json文件的value方法
Dec 31 Python
python对列进行平移变换的方法(shift)
Jan 10 Python
Python基础之文件读取的讲解
Feb 16 Python
pyqt 实现QlineEdit 输入密码显示成圆点的方法
Jun 24 Python
numpy.meshgrid()理解(小结)
Aug 01 Python
python实现猜单词游戏
May 22 Python
浅谈tensorflow中dataset.shuffle和dataset.batch dataset.repeat注意点
Jun 08 Python
聊聊pytorch测试的时候为何要加上model.eval()
May 23 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发电子邮件
2006/10/09 PHP
PHP 7安装调试工具Xdebug扩展的方法教程
2017/06/17 PHP
ExtJS PropertyGrid中使用Combobox选择值问题
2010/06/13 Javascript
浅析Node在构建超媒体API中的作用
2014/07/30 Javascript
JS+CSS相对定位实现的下拉菜单
2015/10/06 Javascript
深入理解jQuery之事件移除
2016/06/02 Javascript
jQuery+ajax实现修改密码验证功能实例详解
2017/07/06 jQuery
使用 Node.js 开发资讯爬虫流程
2018/01/07 Javascript
Vue修改mint-ui默认样式的方法
2018/02/03 Javascript
angularJs-$http实现百度搜索时的动态下拉框示例
2018/02/27 Javascript
vue-cli 如何打包上线的方法示例
2018/05/08 Javascript
详解vue2.0+axios+mock+axios-mock+adapter实现登陆
2018/07/19 Javascript
解决微信小程序中转换时间格式IOS不兼容的问题
2019/02/15 Javascript
JS Thunk 函数的含义和用法实例总结
2020/04/08 Javascript
react 不用插件实现数字滚动的效果示例
2020/04/14 Javascript
只有 20 行的 JavaScript 模板引擎实例详解
2020/05/11 Javascript
vue实现简单跑马灯效果
2020/05/25 Javascript
scrapy自定义pipeline类实现将采集数据保存到mongodb的方法
2015/04/16 Python
使用python将时间转换为指定的格式方法
2018/11/12 Python
python解析含有重复key的json方法
2019/01/22 Python
Python面向对象程序设计构造函数和析构函数用法分析
2019/04/12 Python
解决Opencv+Python cv2.imshow闪退问题
2020/04/24 Python
Python生成并下载文件后端代码实例
2020/08/31 Python
PyTorch中clone()、detach()及相关扩展详解
2020/12/09 Python
CSS3教程(4):网页边框和网页文字阴影
2009/04/02 HTML / CSS
Mavi牛仔裤美国官网:土耳其著名牛仔品牌
2016/09/24 全球购物
挪威户外活动服装和装备购物网站:Bergfreunde挪威
2016/10/20 全球购物
MATCHESFASHION.COM法国官网:英国奢侈品零售商
2018/01/04 全球购物
法国床上用品商店:La Compagnie du lit
2019/12/26 全球购物
本科毕业生专业自荐书范文
2014/02/05 职场文书
委托书的写法
2014/08/30 职场文书
交通事故死亡赔偿协议书
2014/12/03 职场文书
2015年办公室个人工作总结
2015/04/20 职场文书
公司年会主持词范文!
2019/05/07 职场文书
python基于tkinter制作无损音乐下载工具
2021/03/29 Python
微软PC Health Check电脑健康状况检查应用下载(Win11配置检测工具)
2021/06/26 数码科技