我有以下序列化程序定义:
class TestSerializer(serializers.ModelSerializer):
contexts = serializers.SerializerMethodField()
class Meta:
model = Test
fields = (
"id",
"contexts"
)
def get_contexts(self, obj):
return ...
def create(self, data):
print('CREATE')
print(data)
return super().create(data)
def update(self, instance, validated_data):
print('UPDATE')
print(validated_data)
return super().update(instance, validated_data)
并在视图集中使用此类
serializer_class = TestSerializer
queryset = Test.objects.all()
请注意,contexts
字段不是数据库字段。使用GET访问端点时,我会使用
{
"id": 1,
"contexts": [{...}]
}
但是当将相同的数据发送回POST时,则存在两个问题。第一个序列化程序似乎无法关联正确的数据集,因为我总是以create
方法结尾,导致错误
duplicate key value violates unique constraint
,并且在create方法中打印data
时,上下文根本不存在。
答案 0 :(得分:1)
鉴于您使用的是ModelViewSet
,并已将其注册在URL:/api/test/
...
一个POST
请求(例如您描述的请求)确实会尝试创建一个以1
作为id
的新条目。如果已经存在带有id
1
的条目,则不可能。
要进行更新,您需要向详细路线发送一个PATCH
请求。 /api/test/1/
SerializerMethodField
是只读的,不会显示在validated_data
中。您可以在self.context['request'].data.get('contexts')
中访问它。但是我建议为该字段创建另一个序列化器...
class ContextsSerializer(serializers.Serializer):
class Meta:
fields = (...)
class TestSerializer(serializers.ModelSerializer):
contexts = ContextsSerializer(many=False)
如果您希望正确完成操作,则还有更多内容。在不完全知道您要做什么以及为什么的情况下,我不想提出一个完整的解决方案。但是,您可以使用未经request
验证的数据来完成您想做的事情。