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 version 2.7 required, which was not found in the registry
Aug 26 Python
Tensorflow 自带可视化Tensorboard使用方法(附项目代码)
Feb 10 Python
python使用jieba实现中文分词去停用词方法示例
Mar 11 Python
python生成lmdb格式的文件实例
Nov 08 Python
python3+selenium自动化测试框架详解
Mar 17 Python
Python3字符串encode与decode的讲解
Apr 02 Python
python如何实现从视频中提取每秒图片
Oct 22 Python
flask利用flask-wtf验证上传的文件的方法
Jan 17 Python
python实现滑雪者小游戏
Feb 22 Python
如何利用python 读取配置文件
Jan 06 Python
pytorch中index_select()的用法详解
Jan 06 Python
简单介绍Python的第三方库yaml
Jun 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
Mysql的Root密码忘记,查看或修改的解决方法(图文介绍)
2013/06/14 PHP
php parse_str() 函数的定义和用法
2016/05/23 PHP
laravel框架中控制器的创建和使用方法分析
2019/11/23 PHP
php使用event扩展的io复用测试的示例
2020/10/20 PHP
javascript面向对象包装类Class封装类库剖析
2013/01/24 Javascript
js获取URL的参数的方法(getQueryString)示例
2013/09/29 Javascript
jquery dialog open后,服务器端控件失效的快速解决方法
2013/12/19 Javascript
JQuery节点元素属性操作方法
2015/06/11 Javascript
JQuery+Ajax实现数据查询、排序和分页功能
2015/09/27 Javascript
javascript实现查找数组中最大值方法汇总
2016/02/13 Javascript
JS实现含有中文字符串的友好截取功能分析
2017/03/13 Javascript
BootStrap给table表格的每一行添加一个按钮事件
2017/09/07 Javascript
详解如何用babel转换es6的class语法
2018/04/03 Javascript
深入浅析AngularJs模版与v-bind
2018/07/06 Javascript
vue mvvm数据响应实现
2020/11/11 Javascript
原生js中运算符及流程控制示例详解
2021/01/05 Javascript
python调用windows api锁定计算机示例
2014/04/17 Python
python引用DLL文件的方法
2015/05/11 Python
Python中的anydbm模版和shelve模版使用指南
2015/07/09 Python
在Django的URLconf中进行函数导入的方法
2015/07/18 Python
Scrapy框架CrawlSpiders的介绍以及使用详解
2017/11/29 Python
Python datetime和unix时间戳之间相互转换的讲解
2019/04/01 Python
Django使用 Bootstrap 样式修改书籍列表过程解析
2019/08/09 Python
Python3 合并二叉树的实现
2019/09/30 Python
解决更改AUTH_USER_MODEL后出现的问题
2020/05/14 Python
在python中使用pyspark读写Hive数据操作
2020/06/06 Python
大学生新闻专业个人自我评价
2013/11/12 职场文书
医生进修自我鉴定
2014/01/19 职场文书
六查六看自查材料
2014/02/17 职场文书
《天游峰的扫路人》教学反思
2014/04/25 职场文书
优秀毕业生自荐信
2014/06/10 职场文书
党员三严三实心得体会
2014/10/13 职场文书
共青团员自我评价
2015/03/10 职场文书
单位同意报考证明
2015/06/17 职场文书
世界名著读书笔记
2015/06/25 职场文书
欠条范文
2015/07/03 职场文书