Python and Django - 如何在内存和临时文件中使用
Python and Django - How to use in memory and temporary files
我需要一些在内存和临时文件中使用文件操作的示例。
我搜索了很多很好的例子/教程,我只找到了基本的 read/write/append 操作。
我需要了解如何在 Django 中读取在保存 (post) 完成之前上传的文件(图像)。
因为Django是Python,我觉得先了解一下python.
我检查了 Django documentation/examples,但不是很清楚所以我需要先了解 Python 然后在 Django 中操作是如何工作的,而不仅仅是复制和粘贴。
我知道如何使用ImageFields,上传默认操作,我只对使用“内存和临时文件”感兴趣。
我想将它与裁剪功能结合使用。因此用户可以上传 1、2、3... 图像,并使用 javascript 裁剪脚本我在隐藏字段中获取坐标。在 javascript 模拟裁剪后,我向用户展示裁剪后的缩略图,比例
用户可以改变主意,可以 edit/update 或在保存前删除文件。
现在根据文件大小,它可以保存在内存中或写入。
您可以设置用于 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
对象访问数据和文件。
如果您正在查看 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()
您可以看到这与通用 read/write 文件操作非常相似。
如果我理解正确,您正在寻找一种在使用 instance.save()
或类似方法保存上传文件之前访问它的方法。
如果是这样,您可以尝试直接从请求中读取文件:
if my_form.is_valid():
data = request.FILES['myfile'].read()
上传文件时,Django 将执行以下两项操作之一:如果文件较小(我上次检查时小于 2 MB),则将其存储在内存中;如果文件较大,则将其作为临时文件存储在磁盘上。此行为可通过 FILE_UPLOAD_HANDLERS
设置进行配置。因此,您的网络服务器和 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
。
它是在内存中还是在临时文件中通常并不重要,因为接口是相同的。您可以像读取内存文件一样读取临时文件。
我需要一些在内存和临时文件中使用文件操作的示例。
我搜索了很多很好的例子/教程,我只找到了基本的 read/write/append 操作。
我需要了解如何在 Django 中读取在保存 (post) 完成之前上传的文件(图像)。
因为Django是Python,我觉得先了解一下python.
我检查了 Django documentation/examples,但不是很清楚所以我需要先了解 Python 然后在 Django 中操作是如何工作的,而不仅仅是复制和粘贴。
我知道如何使用ImageFields,上传默认操作,我只对使用“内存和临时文件”感兴趣。
我想将它与裁剪功能结合使用。因此用户可以上传 1、2、3... 图像,并使用 javascript 裁剪脚本我在隐藏字段中获取坐标。在 javascript 模拟裁剪后,我向用户展示裁剪后的缩略图,比例
用户可以改变主意,可以 edit/update 或在保存前删除文件。
现在根据文件大小,它可以保存在内存中或写入。
您可以设置用于 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
对象访问数据和文件。
如果您正在查看 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()
您可以看到这与通用 read/write 文件操作非常相似。
如果我理解正确,您正在寻找一种在使用 instance.save()
或类似方法保存上传文件之前访问它的方法。
如果是这样,您可以尝试直接从请求中读取文件:
if my_form.is_valid():
data = request.FILES['myfile'].read()
上传文件时,Django 将执行以下两项操作之一:如果文件较小(我上次检查时小于 2 MB),则将其存储在内存中;如果文件较大,则将其作为临时文件存储在磁盘上。此行为可通过 FILE_UPLOAD_HANDLERS
设置进行配置。因此,您的网络服务器和 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
。
它是在内存中还是在临时文件中通常并不重要,因为接口是相同的。您可以像读取内存文件一样读取临时文件。