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

时间:2017-08-24 16:03:06

标签: python django django-file-upload

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

我搜索了很多好的示例/教程,我找到了基本的读/写/追加操作。

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

因为Django是Python,我认为最好先在python中理解。

我检查了Django文档/示例,但不是很清楚所以我需要首先了解phyton而不是Django如何操作,而不仅仅是复制和粘贴。

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

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

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

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

4 个答案:

答案 0 :(得分:5)

当上传文件时,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

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

答案 1 :(得分:1)

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

有两个内置选项:

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

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

例如,当文件低于特定大小时,将激活并使用InMemoryUploadHandler。文件非常大时使用TemporaryFileUploadHandler。

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

答案 2 :(得分:1)

如果您正在查看特定于Python的(而不是Django),那么您可能会对$ pip install --no-clean git+https://github.com/clab/dynet#egg=dynet 模块感兴趣:

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

调整上述文档中的示例:

tempfile

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

答案 3 :(得分:0)

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

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

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