Django将文件上传到依赖于POST URI的特定目录

kmt*_*kmt 9 directory django upload filenames storage

我想将上传的文件存储到一个特定的目录中,该目录取决于POST请求的URI.也许,我还想将文件重命名为固定的东西(例如文件输入的名称),这样我就可以轻松地grep文件系统等,并避免可能出现的安全问题.

在Django中这样做的首选方法是什么?

编辑:我应该澄清一下,我有兴趣将其作为文件上传处理程序,以避免将大文件两次写入文件系统.

Edit2:我想人们可以将tmp文件'mv'转移到一个新位置.如果在同一个文件系统上,这是一个便宜的操作.

use*_*668 9

修复了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)
Run Code Online (Sandbox Code Playgroud)


olo*_*ney 5

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()
Run Code Online (Sandbox Code Playgroud)

编辑:如何使用 FileUploadHandler 执行此操作?它追踪了代码,似乎您需要做四件事来重新调整 TemporaryFileUploadHandler 的用途以保存在 FILE_UPLOAD_TEMP_DIR 之外:

  1. 扩展TemporaryUploadedFile并重写init () 以通过不同的目录传递给 NamedTemporaryFile。除了我上面显示的 pass 之外,它可以使用 try mkdir 。

  2. 扩展TemporaryFileUploadHandler并重写 new_file() 以使用上述类。

  3. 还可以扩展init () 以接受您想要文件夹所在的目录。

  4. 动态添加请求处理程序,传递从 URL 确定的目录:

    request.upload_handlers = [ProgressBarUploadHandler(request.path.replace('/', '_')]

虽然不简单,但它仍然比从头开始编写处理程序更容易:特别是,您不必编写一行容易出错的缓冲读取。步骤 3 和 4 是必要的,因为我相信默认情况下 FileUploadHandlers 不会传递请求信息,因此如果您想以某种方式使用 URL,则必须单独告诉它。

我真的不建议为此编写自定义 FileUploadHandler 。这确实是责任层次的混合。相对于通过互联网上传文件的速度,进行本地文件复制是微不足道的。如果文件很小,Django 只会将其保留在内存中,而不将其写入临时文件。我有一种不好的预感,当你完成所有这些工作后,却发现你甚至无法衡量性能差异。