Django 已验证的_数据中不存在图像 问题是:

Django 已验证的_数据中不存在图像 问题是:,django,django-rest-framework,Django,Django Rest Framework,我正在尝试实现序列化概要文件模型的序列化程序。不幸的是,传递给序列化程序的update()方法的validated\u数据中不存在image键及其值 设置: 这是我正在测试的环境: Django 1.11.4,djangorestframework 3.6.3,Python 3.6.5 这是我用来向各个端点发出的请求: curl -vvv \ -XPUT \ -H "Authorization:Bearer ${accessToken}" \ -H "Conten

我正在尝试实现序列化概要文件模型的序列化程序。不幸的是,传递给序列化程序的
update()
方法的
validated\u数据中不存在
image
键及其值


设置: 这是我正在测试的环境:
Django 1.11.4
djangorestframework 3.6.3
Python 3.6.5

这是我用来向各个端点发出的请求:

curl -vvv \
     -XPUT \
     -H "Authorization:Bearer ${accessToken}" \
     -H "Content-Type:multipart/form-data" \
     -F "user=http://${baseURL}/users/2;type=application/json" \
     -F "image=@${image1};type=image/png" \
     ${url}
序列化程序代码:

from rest_framework import serializers

class ImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = Image
        fields = ('image',)

    image = serializers.ImageField(required=True)


class ProfileSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Profile
        fields = (
            'url',
            'user',
            'image',
            )

    image = ImageSerializer(required=False, allow_null=True)

    def update(self, instance, validated_data):
        # The documentation tells me it should now work like this:
        uploaded_image = validated_data.pop('image')
        instance.image = ProfileImage.objects.create(image=uploaded_image)
        return super().update(instance, validated_data)
        # but validated_data.pop('image') raises a KeyError which is logical, 
        # since validated_data does not contain an 'image' key.
型号代码:

from django.db import models
from django.contrib.auth import get_user_model

class Image(models.Model):
    image = models.ImageField(null=True, default=None)

    class Meta:
        abstract = True


class ProfileImage(Image):
    pass


class Profile(models.Model):
    user = models.OneToOneField(get_user_model(), related_name='profile')
    image = models.OneToOneField(ProfileImage, related_name='profile', null=True, default=None)
当我在序列化程序的
update()
方法内设置断点并检查
validated\u data
时,图像键值对不存在,这就是为什么
validated\u data.pop('image')
(如建议的)会引发一个键错误


可能的解决办法? 但是,我可以像这样从请求数据中检索图像,并手动更新模型:

def update(self, instance, validated_data):
    uploaded_image = self.context.get('request').data.get('image')
    instance.image = ProfileImage.objects.create(image=uploaded_image)
    return super().update(instance, validated_data)
然而,这对我来说似乎很难理解,因为我认为必须有某种方法使图像出现在
验证的\u数据中


问题:
  • 提议的手动方法是可以接受的,还是一个坏习惯
  • 为什么已验证的_数据中不存在图像键值对
  • 它应该存在吗

到目前为止,我所尝试的: 我在ProfileSerializer中实现了一个
validate()
覆盖,检查了传递给它的
attrs
,图像不在其中

我在ProfileSerializer和ImageSerializer上都实现了
validate_image()
,没有调用任何一个

我在ImageSerializer中实现了一个
validate()
和一个
update()
覆盖,没有一个被调用。

来自:

默认情况下,嵌套序列化程序是只读的。如果你想支持 将操作写入需要创建的嵌套序列化程序字段 create()和/或update()方法以明确指定 应保存子关系

在您的示例中,您应该在
update
方法中手动更新相关对象:

def update(self, instance, validated_data):
    if 'image' in validated_data:
        instance.image.image = validated_data.pop('image')
    ...

    instance.save()
    return instance

问题是请求中的名称
image
与嵌套字段名称
image.image
不匹配

自 这将导致
Serializer.to_internal_value()
跳过

基本上,身体部分只是默默地被忽略了

为了让它工作,我必须将请求更改为:

curl -vvv \
     -XPUT \
     -H "Authorization:Bearer ${accessToken}" \
     -H "Content-Type:multipart/form-data" \
     -F "user=http://${baseURL}/users/2;type=application/json" \
     -F "image.image=@${image1};type=image/png" \
     ${url}

这是一个很好的答案,但我的实际问题是,为什么“图像”不存在于已验证的_数据中(不幸的是,事实并非如此)。我试着澄清一下这个问题。