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实现的登录和操作开心网脚本分享
Jul 09 Python
python处理文本文件实现生成指定格式文件的方法
Jul 31 Python
举例讲解Python中的身份运算符的使用方法
Oct 13 Python
python利用拉链法实现字典方法示例
Mar 25 Python
Python使用while循环花式打印乘法表
Jan 28 Python
Django框架模型简单介绍与使用分析
Jul 18 Python
python实现京东订单推送到测试环境,提供便利操作示例
Aug 09 Python
Pytorch加载部分预训练模型的参数实例
Aug 18 Python
Win10 安装PyCharm2019.1.1(图文教程)
Sep 29 Python
Python闭包装饰器使用方法汇总
Jun 29 Python
通过实例简单了解python yield使用方法
Aug 06 Python
在pycharm中无法import所安装的库解决方案
May 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
在PHP中执行系统外部命令
2006/10/09 PHP
PHP中如何实现常用邮箱的基本判断
2014/01/07 PHP
总结对比php中的多种序列化
2016/08/28 PHP
PHP简单判断iPhone、iPad、Android及PC设备的方法
2016/10/11 PHP
PHP 爬取网页的主要方法
2018/07/13 PHP
修改Laravel自带的认证系统的User类的命名空间的步骤
2019/10/15 PHP
YII2框架中日志的配置与使用方法实例分析
2020/03/18 PHP
javascript实现上传图片前的预览(TX的面试题)
2007/08/20 Javascript
js函数调用的方式
2014/05/06 Javascript
了不起的node.js读书笔记之node.js中的特性
2014/12/22 Javascript
JavaScript在浏览器标题栏上显示当前日期和时间的方法
2015/03/19 Javascript
浅谈js中function的参数默认值
2017/02/20 Javascript
JS实现把一个页面层数据传递到另一个页面的两种方式
2018/08/13 Javascript
微信小程序实现顶部下拉菜单栏
2018/11/04 Javascript
修改layui的后台模板的左侧导航栏可以伸缩的方法
2019/09/10 Javascript
jquery实现购物车基本功能
2019/10/25 jQuery
Vue是怎么渲染template内的标签内容的
2020/06/05 Javascript
深入讲解Python中面向对象编程的相关知识
2015/05/25 Python
Python+PIL实现支付宝AR红包
2018/02/09 Python
Python使用wget实现下载网络文件功能示例
2018/05/31 Python
解决DataFrame排序sort的问题
2018/06/07 Python
Python 如何在字符串中插入变量
2020/08/01 Python
详解PyQt5中textBrowser显示print语句输出的简单方法
2020/08/07 Python
详解python日志输出使用配置文件格式
2021/02/10 Python
CSS3结构性伪类选择器九种写法
2012/04/18 HTML / CSS
详解CSS3:overflow属性
2020/11/17 HTML / CSS
澳大利亚礼品篮网站:Macarthur Baskets
2019/10/14 全球购物
shell程序如何生命变量?shell变量是弱变量吗?
2014/11/10 面试题
毕业生自我推荐
2013/11/04 职场文书
幼儿运动会邀请函
2014/01/17 职场文书
经贸韩语专业大学生职业规划
2014/02/14 职场文书
实习单位评语
2014/04/26 职场文书
珍惜资源保护环境的建议书
2014/05/14 职场文书
入党转正申请自我鉴定
2019/06/25 职场文书
2019年入党思想汇报格式与要求
2019/06/25 职场文书
Nginx防盗链与服务优化配置的全过程
2022/01/18 Servers