django restframework serializer 增加自定义字段操作
作者:NashCyk 发布时间:2023-12-17 20:36:10
在使用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
来源:https://blog.csdn.net/Nash_Cyk/article/details/79064245
猜你喜欢
- 本文实例讲述了Python使用当前时间、随机数产生一个唯一数字的方法。分享给大家供大家参考,具体如下:Python生成当前时间很简单,比Ja
- Python中对象的行为是由它的类型 (Type) 决定的。所谓类型就是支持某些特定的操作。数字对象在任何编程语言中都是基础元素,支持加、减
- 本文实例为大家分享了python实现五子棋游戏的具体代码,供大家参考,具体内容如下checkerboard.pyfrom collectio
- 编写Python SDK代码工程目录结构├──── easyhttp
- Linux环境MySQL服务器级优化讲解 摘要:本节简单介绍了如何在服务器级优化数据库的性能
- 技巧之一:提高使用Request集合的效率 访问一个ASP集合来提取一个值是费时的、占用计算资源的过程。因为这个操作包含了一系列对相关集合的
- 如何发送一个XMLHttpRequest的检索的特定部分HTML标题数据。<html> <head> <tit
- 本文主要是写了一个将指定文件夹下的指定文件类型移动到指定位置,具体内容如下# coding:utf-8import osimport shu
- 因为神奇的中文有时也是会遇到国外同学都不知道原因导致一些神奇滴问题,所以要用更神奇的英文来解决问题。Mac OS的一些:华文细黑:STHei
- 这篇文章主要介绍了Python tkinter常用操作代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,
- 在MySQL中,如何实现Top N及M至N段的记录查询?我们可以利用MySQL中SELECT支持的一个子句——LIMIT——来完成这项功能。
- canal简介由阿里巴巴开源 github地址:https://github.com/alibaba/canalCanal是阿里巴巴开源的一
- 众所周知,Python 支持多种编程范式:过程式(使用基础的语句)、面向对象编程和函数式编程。Python 也提供了其他函数式编程语言的工具
- XML Web Service 是在 Internet 上进行分布式计算的基本构造块。开放的标准以及对用户和应用程序之间的通信和协作的关注产
- 本文实例讲述了JavaScript导出Excel的方法。分享给大家供大家参考。具体实现方法如下:<html xmlns="h
- 本文实例讲述了kNN算法python实现和简单数字识别的方法。分享给大家供大家参考。具体如下:kNN算法算法优缺点:优点:精度高、对异常值不
- 目前在网上搜到的利用 PyCharm 调试远程服务器程序的教程大多都是针对 PyCharm 2020、2019,甚至更早版本,PyCharm
- numpy 中 的random模块有多个函数用于生成不同类型的随机数,常见的有 uniform、rand、random、randint、ra
- MySQL 客户端连接成功后,通过 show [session|global]status 命令 可以提供服务器状态信息,也可以在操作系统上
- 以下的文章主要是对MySQL性能影响关系紧密的五大配置参数的介绍,我前几天在相关网站看见对MySQL性能影响关系紧密的五大配置参数的资料,觉