Django 将文件上传到取决于 POST URI 的特定目录
Posted
技术标签:
【中文标题】Django 将文件上传到取决于 POST URI 的特定目录【英文标题】:Django upload file into specific directory that depends on the POST URI 【发布时间】:2011-01-17 15:35:41 【问题描述】:我想将上传的文件存储到取决于 POST 请求的 URI 的特定目录中。也许,我还想将文件重命名为固定的名称(例如文件输入的名称),这样我就有一种简单的方法来 grep 文件系统等,也可以避免可能的安全问题。
在 Django 中首选的方法是什么?
编辑:我应该澄清一下,我可能有兴趣将其作为文件上传处理程序执行,以避免将大文件两次写入文件系统。
Edit2:我想可以将 tmp 文件“mv”到一个新位置。如果在同一个文件系统上,这是一个便宜的操作。
【问题讨论】:
移动临时文件没问题。 Django 会检查这个案例,如果它丢失了不会抱怨:code.djangoproject.com/browser/django/trunk/django/core/files/… 【参考方案1】:修复了 olooney 示例。它现在正在工作
@csrf_exempt
def upload_video_file(request):
folder = 'tmp_dir2/' #request.path.replace("/", "_")
uploaded_filename = request.FILES['file'].name
BASE_PATH = '/home/'
# create the folder if it doesn't exist.
try:
os.mkdir(os.path.join(BASE_PATH, folder))
except:
pass
# save the uploaded file inside that folder.
full_filename = os.path.join(BASE_PATH, folder, uploaded_filename)
fout = open(full_filename, 'wb+')
file_content = ContentFile( request.FILES['file'].read() )
try:
# Iterate through the chunks.
for chunk in file_content.chunks():
fout.write(chunk)
fout.close()
html = "<html><body>SAVED</body></html>"
return HttpResponse(html)
except:
html = "<html><body>NOT SAVED</body></html>"
return HttpResponse(html)
【讨论】:
我不知道 ContentFile(request.FILES['file'].read()) 函数的来源。 从 django.core.files.base 导入内容文件【参考方案2】:Django 让您可以完全控制保存文件的位置(以及是否)。见:http://docs.djangoproject.com/en/dev/topics/http/file-uploads/
以下示例展示了如何将上传文件的 URL 和名称结合起来,并将文件写入磁盘:
def upload(request):
folder = request.path.replace("/", "_")
uploaded_filename = request.FILES['file'].name
# create the folder if it doesn't exist.
try:
os.mkdir(os.path.join(BASE_PATH, folder))
except:
pass
# save the uploaded file inside that folder.
full_filename = os.path.join(BASE_PATH, folder, uploaded_filename)
fout = open(full_filename, 'wb+')
# Iterate through the chunks.
for chunk in fout.chunks():
fout.write(chunk)
fout.close()
编辑:如何使用 FileUploadHandler 执行此操作?它追溯了代码,似乎您需要做四件事来重新利用 TemporaryFileUploadHandler 以保存在 FILE_UPLOAD_TEMP_DIR 之外:
扩展 TemporaryUploadedFile 并覆盖 init() 以通过不同的目录传递给 NamedTemporaryFile。它可以使用try mkdir,除了我上面显示的pass。
扩展 TemporaryFileUploadHandler 并覆盖 new_file() 以使用上述类。
还扩展 init() 以接受您希望文件夹所在的目录。
动态添加请求处理程序,通过由 URL 确定的目录:
request.upload_handlers = [ProgressBarUploadHandler(request.path.replace('/', '_')]
虽然不简单,但它仍然比从头开始编写处理程序更容易:特别是,您不必编写一行容易出错的缓冲读取。第 3 步和第 4 步是必要的,因为 FileUploadHandlers 默认不传递请求信息,我相信,所以如果你想以某种方式使用 URL,你必须单独告诉它。
我真的不建议为此编写自定义 FileUploadHandler。这真的混合了责任层。相对于通过 Internet 上传文件的速度,进行本地文件复制是微不足道的。如果文件很小,Django 只会将其保存在内存中,而不会将其写入临时文件。我有一种不好的预感,你会得到所有这些工作并发现你甚至无法衡量性能差异。
【讨论】:
当然,我正在寻找与 django.core.files.uploadhandler.TemporaryFileUploadHandler 无关的东西 好的。我会把它作为 the 的答案。我也有同样的想法,但是,对 Django 很陌生,我想和某人核实一下。顺便说一句,ProgressBarUploadHandler 是从哪里来的?我猜,从某个地方复制粘贴?很公平。感谢您为回答这个问题所做的努力。 虽然,不过,我真的希望对此进行更多讨论。例如,应该使用 django/core/files/storage.py 中的东西吗?这是关于什么的? 代码不工作。错误:AttributeError: 'file' object has no attribute 'chunks'
导入你的文件from .forms import UploadFileForm
from somewhere import handle_uploaded_file
以上是关于Django 将文件上传到取决于 POST URI 的特定目录的主要内容,如果未能解决你的问题,请参考以下文章