pythondjangopython-3.6image-uploaddjango-uploads

Django Upload Image in specific folder without FileField or ImageField and MEDIAROOT


My App needs to upload different profile images in different folders inside the static folder. One more thing, I'm not using models, I just want to take the picture I choose in html input file and copy to the specific folder.

Here is my folder tree. Where I want to save the uploaded image is in MYPROJECTFOLDER/static/profile/<TheUserSpecificFolder>/ that's where I don't want to use MEDIA_ROOT, becouse in media root I can't create a specific folder to each user. (I don't know if this is correct, if there is a way to create a specific folder to each user in the /media/ folder without using ImageField or FileField, please tell me).

Here is my folder tree:

MYPROJECTFOLDER
|
|------myproject/
|
|------myapp/
|
|------static
|      |-------profile
|              |------folder_user1
|                     |------ uploadedpicture.jpg #Here is where I want to upload
|                     |------folder_user2

Here is my uploadpic.html

<form action="{% url 'upload' %}" enctype="multipart/form-data" method="POST">
  {% csrf_token %}
  <input type="file" name="avatar" accept="image/gif, image/jpeg, image/png">
  <button type="submit">Upload</button>
</form>

Here is my views.py

from django.shortcuts import render, HttpResponse, redirect
from . import forms
import os

def upload(request):
  img = request.FILES['avatar']
  #This just create the folder where I want to save the image.
  if not os.path.exists('static/profile/' + str(request.session['user_id'])):
    os.mkdir('static/profile/' + str(request.session['user_id']))

  #NOW HERE IS WHERE I WANT TO WRITE THE CODE THAT SAVE THE IMAGE INTO THE FOLDER I JUST CREATED


return redirect('companyedit')

Solution

  • Since you say that:

    I don't want to use MEDIA_ROOT, becouse in media root I can't create a specific folder to each user

    Actually, you can. You asked a similar question before and the answer I posted allows you to do that. Simply put, yes, you can create separate folders for users in MEDIA_ROOT. See this answer.


    Anyway, if you still want to upload images in a custom folder manually, well, you can do it like this:

    def upload(request):
        img = request.FILES['avatar']
        img_extension = os.path.splitext(img.name)[1]
    
        user_folder = 'static/profile/' + str(request.session['user_id'])
        if not os.path.exists(user_folder):
            os.mkdir(user_folder)
    
        img_save_path = "%s/%s%s" user_folder, 'avatar', img_extension
        with open(img_save_path, 'wb+') as f:
            for chunk in img.chunks():
                f.write(chunk)
    

    Attention!

    As per the suggestion made by dahrens in the comment below, here are the reasons why you should keep the static files and media files in separate locations:

    1. Static files are considered to be safe as they come from you, the developer - media files instead come from user land and might need additional attention, so they can not be considered safe without checks.
    2. Media/uploaded files will keep growing as more and more users upload files. With your current approach, you are likely to run out of storage space.
    3. Almost every serious web application hosts the uploaded media files in a separate server, so that storage won't become a problem. That is why it is a good idea to keep uploaded images in MEDIA_ROOT. Because all you have to do is change the value of MEDIA_ROOT and Django will save images there.