Проблема:
Я пытаюсь реализовать сериализатор, который сериализует модель профиля.К сожалению, ключ image
и его значение отсутствуют в validated_data
, передаваемом методу update()
сериализатора.
Настройка:
Это средаЯ проверяю это на:
Django 1.11.4
, djangorestframework 3.6.3
, Python 3.6.5
Это запрос, который я использую для PUT к соответствующей конечной точке:
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')
(как предложено в документации ) вызывает ошибку 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
.
Вопрос (ы):
- Является ли предлагаемый ручной методcceptable или это плохой взлом?
- Почему пара значений ключа изображения отсутствует в validated_data?
- Должна ли она присутствовать?
ЧтоЯ уже пробовал:
Я реализовал переопределение validate()
в ProfileSerializer, проверил attrs
, которые были переданы ему, изображения там не было.
Я реализовал validate_image()
как в ProfileSerializer, так и в ImageSerializer, ни один из которых не был вызван.
Я реализовал validate()
и update()
переопределение в ImageSerializer, ни один из которых не был вызван.