Python Django可写嵌套序列化程序和Django多态
假设我有以下模型:Python Django可写嵌套序列化程序和Django多态,python,sql,django,django-rest-framework,django-polymorphic,Python,Sql,Django,Django Rest Framework,Django Polymorphic,假设我有以下模型: 类数据查询(models.Model): name=models.CharField(…) 类实体(多态模型): 类TargetType(模型.整数选择): 人类=1,uu(“人类”) 动物=2,uu(“动物”) targetType=models.PositiveSmallIntegerField(选项=targetType.choices,null=False) dataQuery=models.OneToOneField(dataQuery,on_delete=mode
类数据查询(models.Model):
name=models.CharField(…)
类实体(多态模型):
类TargetType(模型.整数选择):
人类=1,uu(“人类”)
动物=2,uu(“动物”)
targetType=models.PositiveSmallIntegerField(选项=targetType.choices,null=False)
dataQuery=models.OneToOneField(dataQuery,on_delete=models.CASCADE,null=True,related_name=“targetEntity”)
类HumanEntity(实体):
name=models.CharField(…)
def保存(自身、*args、**kwargs):
self.targetType=Entity.targetType.Human
return super().save(*args,**kwargs)
类动物性(实体):
numPaws=models.PositiveSmallIntegerField(…)
def保存(自身、*args、**kwargs):
self.targetType=Entity.targetType.Animal
return super().save(*args,**kwargs)
使用以下序列化程序:
class HumanSerializer(serializers.ModelSerializer):
name=serializers.TextField(…)
类元:
模型=人类实体
字段=('name',)
类AnimalSerializer(serializers.ModelSerializer):
numPaws=serializers.IntegerField(…)
类元:
模型=动物序列化器
字段=('numPaws',)
类EntityPolicyMorphicsSerializer(可写NestedModelSerializer、多态Serializer):
模型\序列化程序\映射={
HumanEntity:HumanSerializer,
动物性:动物系列化剂,
}
类元:
模型=实体
字段='\uuuu所有\uuuu'
类DataQuerySerializer(可写NestedModelSerializer):
id=序列化程序。只读字段()
name=serializers.CharField(),
targetEntity=EntityPolicyMorphicsSerializer()
类元:
模型=数据查询
字段=('id','name','targetEntity')
我有一个模型DataQuery
,它有一个1:1的映射,要么是AnimalEntity
,要么是HumanEntity
模型。
如果我序列化使用HumanEntity
创建的DataQuery
,我会得到以下(正确)输出:
{
身份证号码:1
名称:“testQuery”
目标:{
resourcetype:“HumanEntity”,
姓名:“约翰·多伊”
}
}
对我的端点的POST
调用也可以工作,创建的DataQuery
和底层HumanEntity
没有任何问题
我无意在内部实体
序列化程序中包含id
,因为这与此API的使用者无关。对他们来说,只需要知道查询可以包含动物或人类
现在我想更新我的DataQuery
实例,并将底层的HumanEntity
更改为AnimalEntity
。
因此,我提出了以下内容:
{
身份证号码:1
名称:“testQuery”
目标:{
资源类型:“动物性”,
numPaws:4
}
}
现在,一些奇怪的事情发生了。没有什么。没有创建AnimalEntity
,并且HumanEntity
也没有更改(如果我通过输入不同的名称更改HumanEntity
,则名称会正确更改)。
可写嵌套的DataQuerySerializer
似乎不太明白应该关闭底层实例(即删除旧实例,创建新实例)
我仔细阅读了相关代码。由于我不想在嵌套模型序列化程序中包含pk
,因此将检索HumanEntity
的现有pk
。不知何故(我想这是由于多态序列化程序),这是从正确的序列化程序AnimalEntitySerializer
中完成的。但由于传递的字段与基础模型不兼容,因此不会发生任何事情
如果我通过将OneToOneField
放置到DataQuery
来反转1:1映射,如下所示:
类数据查询(models.Model):
...
targetEntity=models.OneToOneField(实体,on_delete=models.CASCADE,null=True)
这有点奏效,但不是真的。每次我进行更新(即使不做任何更改),都会创建一个新的HumanEntity
或AnimalEntity
。但是序列化程序尊重PUT
中的更改,并创建正确的模型。(不过,旧版本不会被删除)
我期待什么?
在执行PUT
时,我想更新现有实例,或者,如果我决定切换实体的类型,则创建正确的实例并删除另一个实例。
我不确定是否on_delete=CASCADE
有任何帮助(无论在哪一方),因为我真正需要的是一个字段,上面写着,如果相关字段为空,请删除我自己
我非常清楚,通过覆盖DataQuerySerializer
的update
方法,我可以(可能相当容易)解决这个问题,但这样一来,我就不需要可写序列化器了
也许有什么我忽略了,任何帮助都将不胜感激