Null в ответе, который не должен существовать Django
Когда я отправляю запрос в Postman следующим образом:
он возвращает мне все поля, кроме profile_photo. profile_photo в ответе - null, и я не знаю, в чем проблема. Это должно быть новое uuid имя фотографии.
Вот моя модель:
class User(AbstractBaseUser, PermissionsMixin):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
email = models.EmailField(_('email address'), unique=True)
first_name = models.CharField(max_length=150, blank=True)
last_name = models.CharField(max_length=150, blank=True)
city = models.CharField(max_length=150, blank=True)
description = models.CharField(max_length=1000, blank=True)
profile_photo = models.CharField(max_length=500, blank=True)
date_joined = models.DateTimeField(default=timezone.now)
about = models.TextField(_(
'about'), max_length=500, blank=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
objects = CustomAccountManager()
object = models.Manager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name', 'city']
def __str__(self):
return self.email
Вот мое мнение:
class CustomUserUpdate(generics.UpdateAPIView):
permission_classes = [IsAuthenticated]
queryset = User.objects.all()
serializer_class = UserUpdateSerializer
def get_object(self):
return self.request.user
Это мой сериализатор. Здесь я задаю новое имя фотографии. Когда я печатаю новое имя вот так: print(instance.profile_photo), он показывает мне новое имя файла. Но в ответ я получаю null.
class UserUpdateSerializer(serializers.ModelSerializer):
profile_photo = serializers.FileField(required=False)
class Meta:
model = User
fields = ('email', 'first_name', 'last_name', 'city', 'description', 'profile_photo')
def __init__(self, *args, **kwargs):
super(UserUpdateSerializer, self).__init__(*args, **kwargs)
self.fields['email'].required = False
self.fields['description'].required = False
def update(self, instance, validated_data):
if instance.id == self.context['request'].user.id:
instance.email = validated_data.get('email', instance.email)
instance.first_name = validated_data.get('first_name', instance.first_name)
instance.last_name = validated_data.get('last_name', instance.last_name)
instance.city = validated_data.get('city', instance.city)
instance.description = validated_data.get('description', instance.description)
uploaded_file = validated_data.get('profile_photo', None)
if uploaded_file:
validate_extension(uploaded_file.name)
instance.profile_photo = handle_uploaded_file(uploaded_file)
instance.save()
return instance
def handle_uploaded_file(file):
extension = os.path.splitext(file.name)[1]
new_filename = f"{uuid.uuid4()}{extension}"
destination = open(f'static/user/images/{new_filename}', 'wb+')
for chunk in file.chunks():
destination.write(chunk)
destination.close()
return new_filename
def validate_extension(filename):
extension = os.path.splitext(filename)[1].replace(".", "")
if extension.lower() not in ALLOWED_IMAGE_EXTENSIONS:
raise serializers.ValidationError(
(f'Invalid uploaded file type: {filename}'),
code='invalid',
)
При отправке запросов вы передаете файл на вход сериализатору. Сериализатор проверяет его и сохраняет. До этого момента все в полном порядке.
Теперь при возврате ответа он ожидает файл от instance.profile_photo
, но к удивлению валидатора сериализатора, он содержит строковое значение (т.е. UUID имя файла). Проблема здесь!
Мы получили точку ошибки. Давайте решим ее.
Чтобы решить эту проблему, различайте имена запроса (File) и ответа (File name i.e. UUID string):
class UserUpdateSerializer(serializers.ModelSerializer):
profile_image = serializers.FileField(required=False, write_only=True)
profile_photo = serializers.ReadOnlyField()
class Meta:
model = User
fields = ('email', 'first_name', 'last_name', 'city', 'description', 'profile_photo', 'profile_image')
def __init__(self, *args, **kwargs):
super(UserUpdateSerializer, self).__init__(*args, **kwargs)
self.fields['email'].required = False
self.fields['description'].required = False
def update(self, instance, validated_data):
if instance.id == self.context['request'].user.id:
instance.email = validated_data.get('email', instance.email)
instance.first_name = validated_data.get('first_name', instance.first_name)
instance.last_name = validated_data.get('last_name', instance.last_name)
instance.city = validated_data.get('city', instance.city)
instance.description = validated_data.get('description', instance.description)
uploaded_file = validated_data.get('profile_image', None)
if uploaded_file:
validate_extension(uploaded_file.name)
instance.profile_photo = handle_uploaded_file(uploaded_file)
instance.save()
return instance
Мы решили проблему!
Выпьем!