我需要一些在内存和临时文件中使用文件操作的例子。
我搜索了很多好的示例/教程,我找到了基本的读/写/追加操作。
我需要了解如何在保存(帖子)完成之前在Django中读取上传的文件(图像)。
因为Django是Python,我认为最好先在python中理解。
我检查了Django文档/示例,但不是很清楚所以我需要首先了解phyton而不是Django如何操作,而不仅仅是复制和粘贴。
我知道如何使用ImageFields,上传默认操作,我只对在内存和临时文件中使用"感兴趣。"
我想将它与裁剪功能结合使用。因此用户可以上传1,2,3 ..图像,并使用javascript裁剪脚本我在隐藏字段中获取坐标。在javascript模拟裁剪后,我向用户显示裁剪的缩略图,如何看起来像比率
用户可以改变主意,可以在保存之前编辑/更新或删除文件。
现在根据文件大小,它可以保留在内存中或写入。
答案 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()