我正在尝试实现对Profile模型进行序列化的Serializer。不幸的是,image
键及其值在传递给串行器的validated_data
方法的update()
中不存在。
这是我正在测试的环境:
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_data
时,不存在图像键值对,这就是validated_data.pop('image')
(建议{{3 }})引发KeyError。
但是我可以像这样从请求数据中检索图像并手动更新模型:
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)
但是,这对我来说似乎很棘手,因为我认为也必须有某种方法也可以使图像出现在validated_data
中。
我已经在ProfileSerializer中实现了validate()
覆盖,检查了传递给它的attrs
,图像不在其中。
我已经在ProfileSerializer和ImageSerializer上实现了validate_image()
,但均未调用。
我已经在ImageSerializer中实现了validate()
和update()
覆盖,但没有一个被调用。
答案 0 :(得分:0)
问题是请求中的名称INSERT INTO Student_Interest (Id_Student, Id_Interest, Score)
SELECT Id_Student, Id_Interest, i.Score
FROM Student s CROSS JOIN
(SELECT TOP (5) Score FROM Interest ORDER BY NEWID()) i;
与嵌套字段名称image
不匹配。
自field name didn't match, Serializer.get_value()
returns 'empty'起,
这导致image.image
跳过the field entirely。
基本上,只是默默地忽略了身体部位。
要使其正常运行,我必须将请求更改为此:
Serializer.to_internal_value()
答案 1 :(得分:-1)
来自Django Rest Framework's documentation:
默认情况下,嵌套的序列化器是只读的。如果你想支持 您需要创建对嵌套序列化器字段的写操作 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