michael hannan
michael hannan

Reputation: 173

Image Upload serializer not working but is valid and saving

I've tried everything but I cannot figure out why my images for an Avatar won't save to the media folder in Django.

I am happy the front end is passing form data to the AvatarAPIView and I get the following when I print out the data being passed to the view.

<QueryDict: {'myFile': [<InMemoryUploadedFile: 1965.jpg (image/jpeg)>]}>
[07/Feb/2021 10:48:54] "PUT /api/profile/avatar/ HTTP/1.1" 200 31

view.py

from profiles.api.serializers import (UserDisplaySerializer,
                                  SubscriptionSerializer,
                                  AvatarSerializer)
from profiles.models import CustomUser
from rest_framework import status, viewsets
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.generics import UpdateAPIView, GenericAPIView
from rest_framework import mixins
from rest_framework.parsers import MultiPartParser, FileUploadParser, FormParser

from django.http import HttpResponse


class CurrentUserAPIView(APIView):

    def get(self, request):
        serializer = UserDisplaySerializer(request.user)
        return Response(serializer.data)

    def patch(self, request):
        serializer = UserDisplaySerializer(request.user, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class UserUpdateAPIView(UpdateAPIView):
    queryset = CustomUser.objects.all()
    serializer_class = UserDisplaySerializer


class AvatarAPIView(APIView):
    parser_classes = (MultiPartParser, FormParser)

    def get(self, request):
        serializer = AvatarSerializer(request.user)
        return Response(serializer.data)

    def put(self, request, format=None):
        serializer = AvatarSerializer(
            request.user, data=request.data)
        print(request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

serializer.py

from rest_framework import serializers
from profiles.models import CustomUser, Subscription


class SubscriptionSerializer(serializers.ModelSerializer):

    class Meta:
        model = Subscription
        exclude = ('id', 'user', )


class UserDisplaySerializer(serializers.ModelSerializer):
    subscription = SubscriptionSerializer(read_only=True, many=False)

    class Meta:
        model = CustomUser
        exclude = ('password',)


class AvatarSerializer(serializers.ModelSerializer):

    class Meta:
        model = CustomUser
        fields = ('avatar',)

urls.py

from django.urls import path
from django.conf.urls import include
from profiles.api.views import (CurrentUserAPIView,
                                UserUpdateAPIView,
                                AvatarAPIView,
                                )

from rest_framework import routers


urlpatterns = [
    path("user/", CurrentUserAPIView.as_view(), name="current-user"),
    path("user/update/<int:pk>", UserUpdateAPIView.as_view()),
    path("avatar/", AvatarAPIView.as_view(), name='user-avatar'),
]

models.py

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


class CustomUser(AbstractUser):
    bio = models.CharField(max_length=240, blank=True)
    city = models.CharField(max_length=30, blank=True)
    avatar = models.ImageField(null=True, blank=True)

I can upload files from the Django admin no problems. It's just when running through the serializer I have issues. Particularly because the data passes is_valid() and a code 200 is issued.

I'm half a day deep and I've got nothing.

Upvotes: 1

Views: 610

Answers (1)

Mas Zero
Mas Zero

Reputation: 593

  1. not sure if your user is logged in or not;
  2. as your formdata shows: <QueryDict: {'myFile': [<InMemoryUploadedFile: 1965.jpg (image/jpeg)>]}> [07/Feb/2021 10:48:54] "PUT /api/profile/avatar/ HTTP/1.1" 200 31

In your form data, the "input name" of image is "myFile" while the name of imagefield in your Model and Serializer is "avatar".

Upvotes: 2

Related Questions