【发布时间】:2019-04-26 16:18:56
【问题描述】:
背景
我有两个序列化器:PostSerializer 和 PostImageSerializer,它们都继承了 DRF ModelSerializer。 PostImage 模型通过 related_name='photos' 与 Post 链接。
由于我希望序列化程序执行 update,因此 PostSerializer 会覆盖 ModelSerializer 中的 update() 方法,如官方 DRF 文档中所述。
class PostSerializer(serializers.ModelSerializer):
photos = PostImageSerializer(many=True)
class Meta:
model = Post
fields = ('title', 'content')
def update(self, instance, validated_data):
photos_data = validated_data.pop('photos')
for photo in photos_data:
PostImage.objects.create(post=instance, image=photo)
return super(PostSerializer, self).update(instance, validated_data)
class PostImageSerializer(serializer.ModelSerializer):
class Meta:
model = PostImage
fields = ('image', 'post')
我还定义了一个继承 ModelViewSet 的 ViewSet。
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
最后将 PostViewSet 注册到 DefaultRouter。 (省略代码)
目标
目标很简单。
- 通过 PostMan 发送 PUT 请求,其 url 类似于“PUT http://localhost:8000/api/posts/1/”
- 由于应包含图像文件,因此请求将通过below. 等表单数据完成
问题
我收到 400 响应,错误消息如下。
{
“相片”: [ “这是必填栏。” ],
“标题”: [ “这是必填栏。” ],
“内容”: [ “这是必填栏。” ]
}
(请注意,错误消息可能与 DRF 错误消息不完全吻合,因为它们已被翻译。)
很明显,我的 PUT 字段都没有应用。 所以我一直在挖掘 Django rest 框架源代码本身,并在 ViewSet update() method continues to fail 中发现了序列化程序验证。
我对此表示怀疑,因为我不是通过 JSON 而是通过使用键值对的表单数据提出请求,所以 request.data 没有得到正确验证。
但是,我应该在请求中包含多个图像,这意味着纯 JSON 不起作用。
对于这种情况,最明确的解决方案是什么?
谢谢。
更新
正如 Neil 所指出的,我在 PostSerializer 的 update() 方法的第一行添加了 print(self)。但是,我的控制台上没有打印任何内容。
我认为这是由于我上面的怀疑,因为调用序列化程序 update() 方法的 perform_update() 方法被称为 AFTER serializer is validated。
因此,我的问题的主要概念可以缩小到以下几点。
- 我应该如何修复请求的数据字段,以便 ModelViewSet 的 update() 方法中的验证可以通过?
- 我是否必须重写 ModelViewSet 的 update() 方法(不是 ModelSerializer 中的那个)?
再次感谢。
【问题讨论】:
-
这三个字段都发生了失败。因此,也许可以尝试禁用图像,然后将文本和内容与 json put 一起放置,看看是否有效。如果确实如此,那么至少您知道问题出在哪里。
-
您应该尝试的另一件事是在更新方法的顶部注销(打印)经过验证的数据。这将告诉你是否有任何事情通过。
-
@Neil 感谢您的回复 Neil。我已经要求不发送图像并且它有效。没有发生验证错误并且数据设置正确。关于您的第二条评论,请查看我的更新。
-
哦,那么问题出在图像/表单数据上。我以前没有处理过,所以我不能说你应该做什么。但也许看看文档的解析器部分:django-rest-framework.org/api-guide/parsers/#multipartparser
-
@Neil 哦,我还没想过解析器。我想这将是一个很好的起点。如果有进展,我会做后续评论。再次感谢您的回复。
标签: python django django-rest-framework