【问题标题】:Django Upload Image in specific folder without FileField or ImageField and MEDIAROOT没有 FileField 或 ImageField 和 MEDIAROOT 的特定文件夹中的 Django 上传图像
【发布时间】:2017-12-30 17:23:52
【问题描述】:

我的应用需要在静态文件夹内的不同文件夹中上传不同的头像。 还有一件事,我没有使用模型,我只是想把我在html输入文件中选择的图片复制到特定的文件夹中。

这是我的文件夹树。我要保存上传的图像的位置是MYPROJECTFOLDER/static/profile/<TheUserSpecificFolder>/,那是我不想使用MEDIA_ROOT 的位置,因为在媒体根目录中我无法为每个用户创建一个特定的文件夹。 (我不知道这是否正确,是否有一种方法可以在不使用ImageFieldFileField 的情况下为/media/ 文件夹中的每个用户创建特定文件夹,请告诉我)。

这是我的文件夹树:

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')

【问题讨论】:

  • 为什么不能像在静态目录中一样在媒体目录中创建文件夹?此外,使用相对路径可能会在某些时候失败(即,如果/当您部署代码时)。

标签: python django python-3.6 image-upload django-uploads


【解决方案1】:

既然你这么说:

我不想使用 MEDIA_ROOT,因为在媒体根目录中我无法为每个用户创建特定文件夹

其实可以的。您之前问过similar question,而我发布的答案允许您这样做。简单地说,是的,您可以在 MEDIA_ROOT 中为用户创建单独的文件夹。见this answer


无论如何,如果你还想手动上传自定义文件夹中的图片,那么你可以这样做:

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 文件和 media 文件保存在不同位置的原因:

  1. 静态文件被认为是安全的,因为它们来自您,开发者 - 媒体文件来自用户空间,可能需要额外注意,因此如果没有检查,它们就不能被认为是安全的。
  2. 随着越来越多的用户上传文件,媒体/上传的文件将不断增长。使用您当前的方法,您可能会用完存储空间。
  3. 几乎每个严肃的 Web 应用程序都将上传的媒体文件托管在单独的服务器中,因此存储不会成为问题。这就是为什么将上传的图片保存在MEDIA_ROOT 中是个好主意。因为您所要做的就是更改MEDIA_ROOT 的值,Django 会将图像保存在那里。

【讨论】:

  • 总的来说,值得一提的是静态和媒体文件的分发是一个好主意。主要区别在于静态文件被认为是安全的,因为它们来自您,开发人员 - 媒体文件来自用户空间,可能需要额外注意 - 例如它们可能会增长得更快,如果没有检查,它们就不能被认为是安全的。您还应该在考虑部署的情况下选择合适的位置。关于这个直截了当的解决方案的小问题:应该从 django 设置中解析路径,而不是假设默认的“静态/”。
  • @dahrens 感谢您的建议,我已经相应地更新了我的答案。但是,我省略了关于从设置中读取变量的部分,因为STATICFILES_DIRS 可以列出多个静态目录(然后还有STATIC_ROOT 设置),所以我不想压倒 OP。但希望他们能尽快解决。
  • @xyres,您是忘记关闭文件还是故意忘记关闭文件?
  • @emanuelsanga 使用with open(...) 语句打开文件会在with 块退出时自动关闭文件。请参阅:stackoverflow.com/q/31334061/1925257
猜你喜欢
  • 1970-01-01
  • 2013-04-19
  • 2012-12-11
  • 1970-01-01
  • 2015-01-18
  • 2020-12-08
  • 2011-11-28
  • 2011-12-12
  • 1970-01-01
相关资源
最近更新 更多