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生成器的使用方法
Nov 21 Python
python基于右递归解决八皇后问题的方法
May 25 Python
python算法演练_One Rule 算法(详解)
May 17 Python
python 实现tar文件压缩解压的实例详解
Aug 20 Python
transform python环境快速配置方法
Sep 27 Python
一个可以套路别人的python小程序实例代码
Apr 09 Python
python 中值滤波,椒盐去噪,图片增强实例
Dec 18 Python
关于python 的legend图例,参数使用说明
Apr 17 Python
python 在threading中如何处理主进程和子线程的关系
Apr 25 Python
Django model.py表单设置默认值允许为空的操作
May 19 Python
Python Matplotlib简易教程(小白教程)
Jul 28 Python
Python在线和离线安装第三方库的方法
Oct 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中global和$GLOBALS[]的分析之一
2012/02/02 PHP
php读取EXCEL文件 php excelreader读取excel文件
2012/12/06 PHP
PHP加密函数 Javascript/Js 解密函数
2013/09/23 PHP
Windows下的PHP安装pear教程
2014/10/24 PHP
yii2利用自带UploadedFile实现上传图片的示例
2017/02/16 PHP
十个迅速提升JQuery性能让你的JQuery跑得更快
2012/12/10 Javascript
javascript常用对话框小集
2013/09/13 Javascript
详细介绍8款超实用JavaScript框架
2013/10/25 Javascript
jquery 图片缩放拖动的简单实例
2014/01/08 Javascript
教你如何自定义百度分享插件以及bshare分享插件的分享按钮
2014/06/20 Javascript
JavaScript跨域方法汇总
2014/10/16 Javascript
五种js判断是否为整数类型方式
2015/12/03 Javascript
关于backbone url请求中参数带有中文存入数据库是乱码的快速解决办法
2016/06/13 Javascript
ajax与json 获取数据并在前台使用简单实例
2017/01/19 Javascript
jquery ajaxfileupload异步上传插件
2017/11/21 jQuery
详解关于Angular4 ng-zorro使用过程中遇到的问题
2018/12/05 Javascript
JavaScript面试中常考的字符串操作方法大全(包含ES6)
2020/05/10 Javascript
Python中struct模块对字节流/二进制流的操作教程
2017/01/21 Python
Python rstrip()方法实例详解
2018/11/11 Python
python实现一组典型数据格式转换
2018/12/15 Python
python 普通克里金(Kriging)法的实现
2019/12/19 Python
Python 利用Entrez库筛选下载PubMed文献摘要的示例
2020/11/24 Python
纯css3制作的火影忍者写轮眼开眼至轮回眼及进化过程实例
2014/11/11 HTML / CSS
美国医疗用品、医疗设备和家庭保健用品商店:Medical Supply Depot
2018/07/08 全球购物
英国水族馆和池塘用品购物网站:Warehouse Aquatics
2019/08/29 全球购物
C++如何引用一个已经定义过的全局变量
2014/08/25 面试题
将一个文本文件的内容按倒序打印出来
2015/01/05 面试题
编写一个 C 函数,该函数在一个字符串中找到可能的最长的子字符串,且该字符串是由同一字符组成的
2015/07/23 面试题
艺术设计专业个人求职信范文
2013/12/11 职场文书
校园公益广告语
2014/03/13 职场文书
2014年五一劳动节社区活动总结
2014/04/14 职场文书
经济贸易专业自荐信
2014/06/11 职场文书
高中课前三分钟演讲稿
2014/08/18 职场文书
最美护士演讲稿
2014/08/27 职场文书
Centos系统通过Docker安装并搭建MongoDB数据库
2022/04/12 MongoDB
Sentry的安装、配置、使用教程(Sentry日志手机系统)
2022/07/23 Python