JSRB
JSRB

Reputation: 2613

Why Django doesn't update an image field

I want to build a view that allows the user to update his profile picture. Now in my view the cleaned data returns the current profile image path which then overwrites the existing one one by one. I'm not sure where the issue is.

Also since I use a default image within the model manager, I only want to delete the current imagefield if it isn't the default one.

# View

@require_POST
def update_profile_image(request, username):
    """
    Updates the user profile
    """
    form = ImageUpdateForm(request.POST)
    if form.is_valid():
        image = form.cleaned_data['profile_image']
        print('image ' + str(image))
        user = Account.objects.get(username=request.user.username)
        user.profile_image = image
        user.save()

    return redirect('pollboard')
# Model

class Account(AbstractBaseUser):

    email = models.EmailField(verbose_name='email', max_length=60, unique=True)
    username = models.CharField(max_length=40, unique=True)
    profile_image = models.ImageField(max_length=255, upload_to=get_profile_image_filepath, null=True, blank=True, default=get_default_profile_image())

# Custom Manager

class MyAccountManager(BaseUserManager):

def get_profile_image_filepath(self, filename):
    return f'profile_image/{self.pk}/{"profile_image.png"}'


def get_default_profile_image():
    return "profile_image/Logo_large.png"
# Form

class ImageUpdateForm(forms.ModelForm):
    class Meta:
        model = Account
        fields = ['profile_image']
# Template

<div class="profile-image-modal">
    <form method="post" action="update_profile_image/">
        {% csrf_token %}
        {{ profile_image_form }}
        <button type="submit">Save Image</button>
    </form>
</div>

Upvotes: 0

Views: 166

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476624

You need to pass both request.POST and request.FILES to the form:

@require_POST
def update_profile_image(request, username):
    """
    Updates the user profile
    """
    #               pass request.FILES as well ↓
    form = ImageUpdateForm(request.POST, request.FILES)
    if form.is_valid():
        image = form.cleaned_data['profile_image']
        print('image ' + str(image))
        user = Account.objects.get(username=request.user.username)
        user.profile_image = image
        user.save()

    return redirect('pollboard')

furthermore you should set the encytpe=… [dev-mozilla] of the form to multipart/form-data to encode the file:

<form method="post" enctype="multipart/form-data" action="update_profile_image/">
        {% csrf_token %}
        {{ profile_image_form }}
        <button type="submit">Save Image</button>
    </form>

Upvotes: 2

Related Questions