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

标签:django,restframework,serializer,字段
0
投稿

猜你喜欢

  • Python configparser模块操作代码实例

    2021-11-05 18:48:08
  • 细化解析:MySQL+Webmin轻松创建数据库

    2009-01-14 13:13:00
  • Python3实现建造者模式的示例代码

    2021-05-11 13:30:16
  • SQL Server 数据页缓冲区的内存瓶颈分析

    2012-08-21 10:49:11
  • 三大原因:按照新HTML标准设计网页好处

    2008-11-12 11:23:00
  • python实现用户登录系统

    2023-10-13 13:17:22
  • 详解python中__name__的意义以及作用

    2021-11-20 19:44:24
  • 解析python 中/ 和 % 和 //(地板除)

    2021-04-19 02:05:14
  • 解决Vue警告Write operation failed:computed value is readonly

    2024-04-09 10:49:25
  • 详解爬虫被封的问题

    2021-01-29 15:21:16
  • Python基础教程之异常详解

    2022-02-08 05:48:49
  • Vue+Express实现登录状态权限验证的示例代码

    2024-05-13 09:11:49
  • python实现弹跳小球

    2022-05-30 08:55:08
  • 前端html+css实现动态生日快乐代码

    2024-05-10 10:58:12
  • php生成curl命令行的方法

    2023-07-23 22:19:42
  • python数据可视化之matplotlib.pyplot基础以及折线图

    2023-03-04 22:10:01
  • TensorFlow索引与切片的实现方法

    2022-11-08 16:00:12
  • 使用Python完成15位18位身份证的互转功能

    2021-11-30 03:04:30
  • 用Python输出一个杨辉三角的例子

    2023-06-04 07:32:33
  • python从入门到实践之字典

    2023-05-11 22:20:17
  • asp之家 网络编程 m.aspxhome.com