django restframework serializer 增加自定义字段操作
在使用djangorestframeworkserializer序列化在django中定义的model时,有时候我们需要额外在serializer中增加一些model中没有的字段。有两种方法实现这个目的。
假设现在有一个Animal模型,其中有name,type,country字段,country为外键。我们在序列化Animal时,需要额外增加外键country的area信息。
方法一修改数据库,利用model这里就不多解释,主要来说第二种,不修改django的model,直接使用SerializerMethodField(method_name=None)字段。
classAnimalSerializer(serializers.ModelSerializer): country_area=serializers.SerializerMethodField() classMeta: model=Animal fields=('id','name','type','country','country_area') defget_country_area(self,obj): returnobj.country.area
SerializerMethodFiel是一个read-only字段
当不指定其method_name时,默认为get_field_name
如果使用ModelSerializer并指定字段时,要包含此时定义的字段
补充知识:djangorestframeworkSerializerfield
SerializerMethodField
这是一个只读字段。它通过调用它所连接的序列化类的方法来获得它的值。它可用于将任何类型的数据添加到对象的序列化表示中。
签名:SerializerMethodField(method_name=None)
method_name-要调用序列化对象的方法的名称。如果不包含,则默认为get_
由method_name参数引用的序列化方法应该接受一个参数(除了self),这是要序列化的对象。它应该返回你想要包含在对象的序列化表示中的任何内容。例如:
场景介绍:一个用户往往对应多个角色,而角色字段并不在UserProfile表中,这就需要我们新增角色字段到user序列化中
from.modelsimportUserProfile from.modelsimportUserRole classUserProfileSerializer(serializers.ModelSerializer): """ showlistserializer """ role=serializers.SerializerMethodField() classMeta: model=UserProfile #fields="__all__" fields=["id","username","role","account","really_name","department","tel_phone", "create_time","email","last_time","creator"] defget_role(self,obj): user_id=obj.id roles=[i.role.nameforiinUserRole.objects.filter(user_id=user_id)] roles=",".join(roles) returnroles
相反的场景:我们提交的表单数据存在于多表中(因为表中含有多对多字段),如何验证所有字段,并保存完整的数据到各表中。
刚开始的思路在ModelSerializer中新增未定义字段,然后发现这并不可行。我也犯了SerializerMethodField的错误,但随后去读了serializer的源码,以及了解serializer的顺序,就知道SerializerMethodField仅用于list方法。
问题的突破点到底在哪里呢,在drfserializer官方文档中就有一个知识点,serializer.save(**kwargs),kwargs数据被绑定在serializer.validated_data对象上,当create或update的时候就会被添加进数据库,相当于validated_data.update(kwargs)
实际源码不是这样子,但也就是这么个意思。
重写Serializercreate,update方法
fromrest_framework.utilsimportmodel_meta defcreate(self,validated_data): field=validated_data.pop('field_name') validated_data=validated_data instance=Model.objects.create(**validated_data) #...外键表的操作 returninstance defupdate(self,instance,validated_data): field=validated_data.pop('field_name') info=model_meta.get_field_info(instance) forattr,valueinvalidated_data.items(): ifattrininfo.relationsandinfo.relations[attr].to_many: field=getattr(instance,attr) field.set(value) else: setattr(instance,attr,value) instance.save() #... returninstance
以上这篇djangorestframeworkserializer增加自定义字段操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。