Why won't my image save to my media directory?

Question:

I’m using Django. My image is saving when my form is submitted, but it is not saving to my media directory. It is only saving the file. For example, it is saving as "file.png" but not "avatars/file.png". I will note that it is saving as expected from within the admin portal.

Here are my files:

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

class Profile(models.Model):
    user = models.OneToOneField(get_user_model(), on_delete=models.CASCADE)
    avatar = models.ImageField(default='avatars/Screenshot_2022-11-30_at_7.18.28_PM.png', upload_to='avatars/')
    header = models.FileField(default='headers/Screenshot_2022-11-30_at_7.18.28_PM.png', upload_to='headers/')
    followers = models.ManyToManyField(get_user_model(), related_name='followers', blank=True)
from django.shortcuts import render, redirect, HttpResponseRedirect
from django.contrib.auth import get_user_model
from django.views.generic import ListView, DetailView, View
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Profile

def updateProf(request):

    Profile.objects.filter(user_id=request.POST['user_id']).update(avatar=request.FILES['avatar'])
    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
{% extends 'base.html' %}
{% load crispy_forms_tags %}

{% block content %}
<div class="signup-form">
    <h2>Edit profile</h2>
    <form method="post" action="/update-prof" enctype="multipart/form-data">
        {% csrf_token %}
        <input type="hidden" name="user_id" value="2">
        <input type="file" name="avatar">
        <button class="btn btn-success" type="submit">Save changes</button>
    </form>
</div>
{% endblock %}

And my settings/urls file:

MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
] + static(
    settings.MEDIA_URL, document_root=settings.MEDIA_ROOT
)

I thought that adding the enctype field/request.FILES would solve the issue, but it didn’t. Anyone know how I can get the file to save to avatars/ ?

Asked By: neesam

||

Answers:

The .update() method works at the database level and will ignore upload_to. It may also overwrite other users’ avatars if the same filename is used when it should actually store the file using a unique filename.

The correct way is to use a proper form to update data based on user input, but if you are in a hurry this should also work:

try:
    profile = Profile.objects.get(user_id=request.POST['user_id'])
    profile.avatar = request.FILES['avatar']
    profile.save()
except Profile.DoesNotFound:
    return HttpResponseNotFound("User not found")
Answered By: Selcuk
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.