Null в ответе, который не должен существовать Django

Когда я отправляю запрос в Postman следующим образом: enter image description here

он возвращает мне все поля, кроме 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

Мы решили проблему!

Выпьем!

Вернуться на верх