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中使用SAX解析xml实例
Nov 21 Python
简单的编程0基础下Python入门指引
Apr 01 Python
使用Python脚本来控制Windows Azure的简单教程
Apr 16 Python
打包发布Python模块的方法详解
Sep 18 Python
Python脚本实现自动将数据库备份到 Dropbox
Feb 06 Python
django使用图片延时加载引起后台404错误
Apr 18 Python
对pycharm代码整体左移和右移缩进快捷键的介绍
Jul 16 Python
Django分页查询并返回jsons数据(中文乱码解决方法)
Aug 02 Python
Python List cmp()知识点总结
Feb 18 Python
Python网络编程之使用TCP方式传输文件操作示例
Nov 01 Python
Python容器类型公共方法总结
Aug 19 Python
calendar在python3时间中常用函数举例详解
Nov 18 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+jquery编码方面的一些心得(utf-8 gb2312)
2010/10/12 PHP
php获取文章上一页与下一页的方法
2014/12/01 PHP
PHP+MySQL插入操作实例
2015/01/21 PHP
php截取字符串函数分享
2015/02/02 PHP
php mysql procedure实现获取多个结果集的方法【基于thinkPHP】
2016/11/09 PHP
php解决DOM乱码的方法示例代码
2016/11/20 PHP
获取URL地址中的文件名和参数的javascript代码
2009/09/02 Javascript
js中的replace方法使用介绍
2013/10/28 Javascript
jquery xMarquee实现文字水平无缝滚动效果
2014/04/29 Javascript
javascript文本模板用法实例
2015/07/31 Javascript
编写高质量JavaScript代码的基本要点
2016/03/02 Javascript
用 js 的 selection range 操作选择区域内容和图片
2017/04/18 Javascript
打造通用的匀速运动框架(实例讲解)
2017/10/17 Javascript
node.js到底要不要加分号浅析
2018/07/11 Javascript
React Component存在的几种形式详解
2018/11/06 Javascript
OpenLayer3自定义测量控件MeasureTool
2020/09/28 Javascript
[18:16]sakonoko 2017年卡尔集锦
2018/02/06 DOTA
[51:17]完美世界DOTA2联赛循环赛Inki vs DeMonsTer 第二场 10月30日
2020/10/31 DOTA
浅析Python中的join()方法的使用
2015/05/19 Python
详解Django缓存处理中Vary头部的使用
2015/07/24 Python
Python实现身份证号码解析
2015/09/01 Python
浅谈django rest jwt vue 跨域问题
2018/10/26 Python
python函数的作用域及关键字详解
2019/08/20 Python
Django框架创建项目的方法入门教程
2019/11/04 Python
Python 音频生成器的实现示例
2019/12/24 Python
Python使用urllib模块对URL网址中的中文编码与解码实例详解
2020/02/18 Python
keras多显卡训练方式
2020/06/10 Python
火山动力Java笔试题
2014/06/26 面试题
党支部活动策划方案
2014/08/18 职场文书
继承公证书格式
2015/01/26 职场文书
2015年公民道德宣传日活动总结
2015/03/23 职场文书
三严三实·严以律己心得体会
2016/01/13 职场文书
分享:关于学习的励志名言赏析
2019/08/16 职场文书
发言稿之优秀教师篇
2019/09/26 职场文书
一文读懂go中semaphore(信号量)源码
2021/04/03 Golang
Java Kafka 消费积压监控的示例代码
2021/07/01 Java/Android