Django 将文件上传到取决于 POST URI 的特定目录

发布于 2024-08-21 09:24:49 字数 257 浏览 6 评论 0原文

我想将上传的文件存储到取决于 POST 请求的 URI 的特定目录中。也许,我还想将文件重命名为固定的名称(例如文件输入的名称),这样我就有一种简单的方法来 grep 文件系统等,并避免可能的安全问题。

在 Django 中执行此操作的首选方法是什么?

编辑:我应该澄清,我有兴趣可能将其作为文件上传处理程序来执行,以避免将大文件写入文件系统两次。

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

I'd like to store uploaded files into a specific directory that depends on the URI of the POST request. Perhaps, I'd also like to rename the file to something fixed (the name of the file input for example) so I have an easy way to grep the file system, etc. and also to avoid possible security problems.

What's the preferred way to do this in Django?

Edit: I should clarify that I'd be interested in possibly doing this as a file upload handler to avoid writing a large file twice to the file system.

Edit2: I suppose one can just 'mv' the tmp file to a new location. That's a cheap operation if on the same file system.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

玩心态 2024-08-28 09:24:49

修复了 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)

Fixed olooney example. It is working now

@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)
太阳哥哥 2024-08-28 09:24:49

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 之外:

  1. extend TemporaryUploadedFile 并覆盖 init() 以通过不同的目录传递给 NamedTemporaryFile。它可以使用 try mkdir 除了上面显示的 pass 之外。

  2. 扩展 TemporaryFileUploadHandler 和覆盖 new_file() 以使用上述类。

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

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

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

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

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

Django gives you total control over where (and if) you save files. See: http://docs.djangoproject.com/en/dev/topics/http/file-uploads/

The below example shows how to combine the URL and the name of the uploaded file and write the file out to disk:

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

Edit: How to do this with a FileUploadHandler? It traced down through the code and it seems like you need to do four things to repurpose the TemporaryFileUploadHandler to save outside of FILE_UPLOAD_TEMP_DIR:

  1. extend TemporaryUploadedFile and override init() to pass through a different directory to NamedTemporaryFile. It can use the try mkdir except for pass I showed above.

  2. extend TemporaryFileUploadHandler and override new_file() to use the above class.

  3. also extend init() to accept the directory where you want the folder to go.

  4. Dynamically add the request handler, passing through a directory determined from the URL:

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

While non-trivial, it's still easier than writing a handler from scratch: In particular, you won't have to write a single line of error-prone buffered reading. Steps 3 and 4 are necessary because FileUploadHandlers are not passed request information by default, I believe, so you'll have to tell it separately if you want to use the URL somehow.

I can't really recommend writing a custom FileUploadHandler for this. It's really mixing layers of responsibility. Relative to the speed of uploading a file over the internet, doing a local file copy is insignificant. And if the file's small, Django will just keep it in memory without writing it out to a temp file. I have a bad feeling that you'll get all this working and find you can't even measure the performance difference.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文