django restframework serializer 增加自定义字段操作

在使用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 增加自定义字段操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • django rest framework 自定义返回方式

    大家在用Django Rest Framework的时候会发现默认继承后,增删改查的返回信息都是一段data,这是因为我实际是状态码和信息你在调用api的时候是看不到的,仅仅如此么?并不是这样,在我前端调用后端的时候,实际上相关的code和msg是能看得到的,但是我们在普通的调用api他只是单单的返回data信息,这个是不够我们满足需求的,毕竟我们不仅仅需要用前端需调用,下面我们来自定义Response返回信息 Django(2.0) Django Rest Framework Python3.

  • Django-rest-framework中过滤器的定制实例

    1.定义一个自定义的filter.py模块,增加一个新的过滤类 import django_filters #这个Q可以支持表查询,单下划线获取表字段,双下划线获取关联表, from django.db.models import Q #引入自己的模型 from app.item.models import ItemCategory #自定义的过滤类,需要继承django_filter.rest_framework中的FilterSet类 class ItemCategoryFilter(dja

  • django自带serializers序列化返回指定字段的方法

    django orm 有个defer方法,指定模型排除的字段. 如下返回的Queryset, 排除'username', 'id'. users=models.UserInfo.objects.defer('username','id') 或users=models.UserInfo.objects.filter(...).defer('username','id') 再如下,使用django自带serializers进行序列,发现序列化的数据仍存在'username', 'id'这两个字段.

  • django Serializer序列化使用方法详解

    Serializer序列化器 定义Serializer 1. 定义方法 Django REST framework中的Serializer使用类来定义,须继承自rest_framework.serializers.Serializer. 例如,我们已有了一个数据库模型类BookInfo class BookInfo(models.Model): btitle = models.CharField(max_length=20, verbose_name='名称') bpub_date = mode

  • django restframework serializer 增加自定义字段操作

    在使用django restframework serializer 序列化在django中定义的model时,有时候我们需要额外在serializer中增加一些model中没有的字段.有两种方法实现这个目的. 假设现在有一个Animal模型,其中有name, type, country字段,country为外键.我们在序列化Animal时,需要额外增加外键country的area信息. 方法一修改数据库,利用model 这里就不多解释,主要来说第二种,不修改django的model,直接使用S

  • SQL server 自增ID--序号自动增加的字段操作

    1.SQL server中创建表,带有自增列. create table Test_Table(Id int Identity(1,1), Name varchar(20)); 这里用到了IDENTITY 关键字.IDENTITY(a,b),a b均为正整数,a表示开始数,b表示步长. IDENTITY(1,1)就代表从1开始,每次增加1. 现在插入两条数据: insert into Test_Table(Name) values ('Mr.Tom'); insert into Test_Tab

  • Django的restframework接口框架自定义返回数据格式的示例详解

    在前后端分离是大趋势的背景下,前端获取数据都是通过调用后台的接口来获取数据微服务的应用越来越多.Django是Python进行web应用开发常用的web框架,用Django框架进行web应用框架减少了很多工作,通常用很少量的代码就可以实现数据的增.删.改.查的业务应用,同样用Django的restframework的框架对外发布接口也是非常的简单方便,几行代码就可以将数据对象通过接口的方式提供服务.因为在实际开发过程中接口的返回数据有一定的格式,本文介绍通过自定义Response返回对象来自定义

  • django模型动态修改参数,增加 filter 字段的方式

    我就废话不多说啦,还是直接看代码吧! kwargs = { # 动态查询的字段 } # 选择deleted_datetime为空的记录 if exclude_deleted: kwargs[ 'deleted_datetime__isnull' ] = True # 选择特的category if category is not None: kwargs[ 'category' ] = category # 特定的用户 if current_user_only: kwargs[ 'user' ]

  • django restframework序列化字段校验规则

    目录 一.怎么校验创建的项目名是否是唯一的,当项目名name字段不唯一,怎么设置提示信息? 二.项目名称中必须得包含“项目”2字 三.单个字段进行校验:项目名称不能多于10个字 四.多字段进行校验: 五.to_internal_value方法,是所有字段开始进行校验时的入口方法(最先调用的方法) 六.to_representation方法,是序列化输出的入口方法 一.怎么校验创建的项目名是否是唯一的,当项目名name字段不唯一,怎么设置提示信息? class ProjectsSerializer

  • Django Serializer HiddenField隐藏字段实例

    Django rest_framework serializer.HiddenField(default=serializer.CurrentUser()) 在用Dajngo RestFramework时, 有时候需要这么一个场景,前端不需要传一个或多个字段,这些字是直接根据用户登录信息判断自动赋值的,如果用mixin和viewset进行搭配写接口,要么重写create, update等方法,要么就是在serializer_class时就定义默认值,而第二种方法明显简单一些. 具体看代码 # 假

  • Django+RestFramework API接口及接口文档并返回json数据操作

    系统:ubuntu18.04 x64 GitHub:https://github.com/xingjidemimi/DjangoAPI.git 安装 pip install django==2.1.5 pip install djangorestframework # rest api pip install coreapi pygments markdown # 自动化接口文档 API示例 创建django项目 django-admin startproject DjangoAPI 创建应用

  • 在django中自定义字段Field详解

    Django的Field类中方法有: to_python() # 把数据库数据转成python数据 from_db_value() # 把数据库数据转成python数据 get_pre_value() # 把python数据压缩准备存入数据库 get_db_pre_value() # 把压缩好的数据转成数据库查询集 get_prep_lookup() # 指定过滤的条件 value_to_string() # 数据序列化 如果创建的Field比字符串,日期,整数等更复杂的数据结构,可能需要重写t

  • django xadmin action兼容自定义model权限教程

    如标题.最近在研究xadmin,发现文档确实比较少,自己只能连滚带爬- 起因 因为想做一个审批的功能,用xadmin acrtion来实现.本来想用模块现有"change"字段控制权限,但是发现使用"change"字段控制权限的话,会把自带的 "delete" action 暴露出来,这不是我想要的. 所以在模块里添加了一个"approver"字段,用以控制权限. 代码 首先修改模块的 "Meta",增加权

  • django认证系统实现自定义权限管理的方法

    本文记录使用django自带的认证系统实现自定义的权限管理系统,包含组权限.用户权限等实现. 0x01. django认证系统 django自带的认证系统能够很好的实现如登录.登出.创建用户.创建超级用户.修改密码等复杂操作,并且实现了用户组.组权限.用户权限等复杂结构,使用自带的认证系统就能帮助我们实现自定义的权限系统达到权限控制的目的. 0x02. 认证系统User对象 User对象顾名思义即为表示用户的对象,里面的属性包括: username password email first_na

随机推荐