Django Загрузить изображение в определенную папку без FileField или ImageField и MEDIAROOT

Моему приложению необходимо загружать разные изображения профиля в разные папки внутри статической папки. Еще одна вещь, я не использую модели, я просто хочу сделать снимок, который я выбираю во входном html-файле, и скопировать в определенную папку.

Вот мое дерево папок. Где я хочу сохранить загруженное изображение, так это в MYPROJECTFOLDER/static/profile/<TheUserSpecificFolder>/, где я не хочу использовать MEDIA_ROOT, потому что в корне мультимедиа я не могу создать отдельную папку для каждого пользователя. (не знаю, правильно ли это, если есть способ создать для каждого пользователя в папке /media/ конкретную папку без использования ImageField или FileField, подскажите пожалуйста).

Вот мое дерево папок:

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

Вот мой 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>

Вот мой 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')

person Sergio Mendez    schedule 30.12.2017    source источник
comment
Почему вы не можете создать папку в каталоге мультимедиа так же, как в статическом каталоге? Кроме того, использование относительных путей может привести к сбою в какой-то момент (например, если/когда вы развернете свой код).   -  person    schedule 30.12.2017


Ответы (1)


Поскольку вы говорите, что:

Я не хочу использовать MEDIA_ROOT, потому что в корне носителя я не могу создать отдельную папку для каждого пользователя.

На самом деле, вы можете. Вы уже задавали похожий вопрос, и опубликованный мной ответ позволяет вам сделай это. Проще говоря, да, вы можете создавать отдельные папки для пользователей в MEDIA_ROOT. См. этот ответ.


В любом случае, если вы все еще хотите загружать изображения в пользовательскую папку вручную, вы можете сделать это следующим образом:

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)

Внимание!

Согласно предложению dahrens в комментарии ниже, вот причины, по которым вы должны сохранять static< /strong> файлы и файлы медиа в разных местах:

  1. Статические файлы считаются безопасными, поскольку они исходят от вас, разработчика, а мультимедийные файлы поступают с территории пользователя и могут потребовать дополнительного внимания, поэтому их нельзя считать безопасными без проверок.
  2. Медиа/загруженные файлы будут расти, так как все больше и больше пользователей загружают файлы. С вашим текущим подходом у вас, вероятно, закончится место для хранения.
  3. Почти каждое серьезное веб-приложение размещает загруженные медиафайлы на отдельном сервере, так что проблем с хранением не возникнет. Вот почему рекомендуется хранить загруженные изображения в MEDIA_ROOT. Потому что все, что вам нужно сделать, это изменить значение MEDIA_ROOT, и Django сохранит туда изображения.
person xyres    schedule 30.12.2017
comment
В целом стоит отметить, что раздача статических и медиафайлов — хорошая идея. Основное отличие состоит в том, что статические файлы считаются безопасными, поскольку они исходят от вас, разработчика, а мультимедийные файлы вместо этого поступают с пользовательской земли и могут потребовать дополнительного внимания, например. они могут расти намного быстрее, и их нельзя считать безопасными без проверок. Вы должны выбрать правильное место с учетом развертывания. Небольшая придирка к этому прямому решению: путь должен быть разрешен из настроек django вместо того, чтобы предполагать «статический /» по умолчанию. - person dahrens; 30.12.2017
comment
@dahrens Спасибо за ваши предложения, я соответствующим образом обновил свой ответ. Однако я пропустил часть о чтении переменных из настроек, потому что в STATICFILES_DIRS может быть указано более одного статического каталога (а также есть STATIC_ROOT настройки), поэтому я не хотел перегружать OP. Но, надеюсь, скоро разберутся. - person xyres; 30.12.2017
comment
@xyres, ты забыл закрыть файл или сделал это намеренно? - person emanuel sanga; 14.07.2021
comment
@emanuelsanga Открытие файла с помощью оператора with open(...) автоматически закрывает файл при выходе из блока with. См.: stackoverflow.com/q/31334061/1925257. - person xyres; 14.07.2021
comment
Ага, с благодарностью @xyres - person emanuel sanga; 14.07.2021