Python 和 Django - 如何在内存和临时文件中使用

Posted

技术标签:

【中文标题】Python 和 Django - 如何在内存和临时文件中使用【英文标题】:Python and Django - How to use in memory and temporary files 【发布时间】:2018-02-02 14:42:54 【问题描述】:

我需要一些使用内存和临时文件的文件操作示例。

我搜索了很多很好的示例/教程,但我发现只有基本的读/写/追加操作。

我需要了解如何在 Django 中读取在保存(发布)完成之前上传的文件(图像)。

因为django是python,我觉得还是先用python理解比较好。

我查看了 Django 文档/示例,但不是很清楚,所以我需要先了解 Python 中的操作,然后再了解 Django 中的操作是如何工作的,而不仅仅是复制和粘贴。

我知道如何使用ImageFields,上传默认操作,我只对使用“内存和临时文件”感兴趣。

我想将它与裁剪功能结合使用。因此,用户可以上传 1、2、3... 图像,并使用 javascript 裁剪脚本获得隐藏字段中的坐标。在javascript模拟裁剪后,我向用户显示裁剪的缩略图,比例如何

用户可以改变主意,可以在保存之前编辑/更新或删除文件。

现在根据文件大小,它可以保存在内存中或写入。

【问题讨论】:

我觉得你想知道如何将图像上传到 django 服务器。对吗? 我知道如何上传图片,使用 ImageField 等,我需要一些关于内存和临时文件的特定内容 我试图写下我能从你的问题中得到的最好的答案。随意添加您正在寻找的内容作为评论。 如果您能详细说明您想对内存中/临时文件做什么,那将会有所帮助。 Django 中的一切都建立在原生 python IO 库之上。 docs.python.org/3/tutorial/… 好的,现在我明白了你想要达到的目标。在这种情况下,您实际上不需要将文件发送到服务器。只有当用户接受裁剪时,才能在客户端裁剪和预览并保存到服务器 【参考方案1】:

当一个文件被上传时,Django 会做以下两件事之一:如果文件很小(我上次检查时小于 2 MB),则将其存储在内存中,如果文件很大,则将其作为临时文件存储在磁盘上。此行为可通过 FILE_UPLOAD_HANDLERS 设置进行配置。因此,您的 Web 服务器和 Django 负责实际的上传和存储,但您的工作是在请求结束之前处理文件,否则文件将被删除。

可以通过request.FILES 属性访问上传的文件。 FILES 中的每个键都将与<form> 中输入的文件名相匹配。该值是一个UploadedFile 对象,它是一个可用于读取文件数据的流。

例如,假设您有一个<input name="img" type="file" />,并且您想检测图像是否完全是白色的。您不需要为此存储文件,只需将其加载到内存中,对其进行处理以获取结果,然后将其丢弃。

from PIL import Image

def some_view(request):
    if request.method == 'POST':
        img_file = request.FILES['img']

        if img_file.size > 2000000:
            return HttpResponseBadRequest()

        img = Image.open(img_file)

        # analyze the image...

另一种可能性是有人上传了一个非常大的备份文件(比如说 2 GB),而您需要将它存储在某个地方。这实际上是同一件事,除了我们将文件以块的形式读入内存,然后将每个块写入其他地方的磁盘,以便在请求完成后将其保存。

def some_view(request):
    if request.method == 'POST':
        backup_file = request.FILES['backup_file']
        with open('some/file/name.bak', 'wb+') as destination:
            for chunk in backup_file.chunks():
                destination.write(chunk)

        # file is saved

请求结束后,上传的文件存储在some/file/name.bak

它是在内存中还是在临时文件中通常并不重要,因为接口是相同的。您可以像读取内存文件一样读取临时文件。

【讨论】:

【参考方案2】:

您可以设置用于 Django 表单的上传处理程序:https://docs.djangoproject.com/en/1.11/ref/files/uploads/#module-django.core.files.uploadhandler

有两个内置选项:

in memory temporary file

Django 的工作方式似乎是遍历所有上传处理程序的列表:https://docs.djangoproject.com/en/1.11/topics/http/file-uploads/#upload-handlers

对于每个上传处理程序,它将检查特定条件,如果该条件为真,它将激活并使用该上传处理程序。

例如,InMemoryUploadHandler 在文件小于一定大小时被激活和使用。当文件非常大时使用 TemporaryFileUploadHandler。

您将能够从request 对象访问数据和文件。

【讨论】:

【参考方案3】:

如果您正在查看特定于 Python(而不是 Django),那么听起来您可能对 tempfile 模块感兴趣:

https://docs.python.org/3/library/tempfile.html

改编自上述文档中的示例:

import tempfile

fp = tempfile.TemporaryFile()
fp.write(b'Hello world!')
# Closing automatically deletes the tempfile
fp.close()

您可以看到这与通用读/写文件操作非常相似。

【讨论】:

我尝试先了解如何在 python 中工作,然后我去 Django【参考方案4】:

如果我理解正确,您正在寻找一种在使用instance.save() 或类似方法保存上传文件之前访问它的方法。

如果是这种情况,您可以尝试直接从请求中读取文件:

if my_form.is_valid():
    data = request.FILES['myfile'].read()

【讨论】:

以上是关于Python 和 Django - 如何在内存和临时文件中使用的主要内容,如果未能解决你的问题,请参考以下文章

Linux如何去部署Django (Nginx + uwsgi + Python3 + Django)

如何使用 django 保持 tensorflow 会话在内存中运行

Python采集linux服务器数据在Django Web界面展示

Python Django:在内存中创建文件对象而不实际创建文件

07.Django-缓存

07.Django-缓存