搜索

cover

django 不使用imagefield 实现多图上传(大容量图片2.5MB以上)

染念 染念

因为某些原因,不想使用imagefield字段,而是将上传的所有图片地址统一返回前端

之前在

一文中提出了这样的方法,但是今天前端的朋友给我反馈
QQ截图20200905215413.png

当时看见这个,我还不太相信,于是去测试了一番api
QQ截图20200905215509.png

哇,生成这么多残缺的图片

QQ截图20200905215601.png

测试期间生成的图片实在有些多..

原版

save_path = pathlib.Path(settings.MEDIA_ROOT) / get_type / f'{uuid.uuid4().hex}{pathlib.Path(form)}'
    if not pathlib.Path(settings.MEDIA_ROOT).is_dir():
        pathlib.Path(settings.MEDIA_ROOT).mkdir(parents=True)
    for content in img.chunks():
        save_path.write_bytes(content)
        ready_save.append((pathlib.Path(settings.MEDIA_URL) / get_type /
                           f'{save_path.name}').as_posix())
        save_path = pathlib.Path(settings.MEDIA_ROOT) / get_type / f'{uuid.uuid4().hex}{pathlib.Path(form)}'

看源代码...就发现了问题
save_path 的重新赋值多余了...,可以看看之前的文章,每次的for已经赋值过了,我想为什么会存在,可能是我之前从os改为pathlib时,没有改完全吧。

还有为什么出了这么多的uri,我们看返回的关键字典ready_save,原来这里的ready_save在for里有问题,为什么有问题呢?
这也是我在这里讲的为什么是大容量图片优化版!!!,对于上次的文章代码来说,出了save_path 赋值重复这个小问题,ready_save在哪都没有问题

我们首先得print(content)看看,再增加个区分符
QQ截图20200905220955.png

这样我们就能发现问题,大容量的图片,content分两次出来了,每次都只是部分图片信息,所以保存的图片才是残缺的,而小容量的图片for就只有一次,所以content根本不需要拼接!!!所以我才说在哪都一样。

这里放出优化版的

insert_content = b''
for content in img.chunks():
  insert_content += content
save_path.write_bytes(insert_content)
ready_save.append((pathlib.Path(settings.MEDIA_URL) / get_type /
                                   f'{save_path.name}').as_posix())

注意图片信息已经写入的是二进制,所以我们得赋值个二进制编码!!!
然后我们人为的来拼接,再去读取写入

到这里,可能会有人问,chunks()是什么啊

我看到有对这个的阐述

class UploadedFile

在文件上传的期间,实际的文件数据被存储在request.FILES。在这个字典中的每一项都是一个UploadedFile对象或者是子类的对象。这是一个对已经上传文件的简单封装,你可以通过以下方法进行访问上传的内容。

方法:

read()

从该文件中读取整块上传的数据,使用这个方法必须小心,如果该上传的文件特别大,它将使得你的系统崩溃,相反你可以使用chunks()方法来一小块小块的读取到内存中。

multiple_chunks(chunk_size=None)

如果上传的文件足够大需要在多个块(chunks)中进行读取,将会返回True。默认情况下,这将会是任何大于2.5 MB的文件,但是这个是可以配置的。

chunks()

这个一个返回文件chunks的生成器。如果multiple_chunks()为True,你应该在循环中使用这个方法而不是read()。

实际上,经常最简单的使用方法是总是使用chunks()。然后循环这个chunks()方法而不是使用read(),这样确保大文件不会过分占用你的系统内存。

引用https://www.cnblogs.com/baishoujing/p/7209886.html

看完了这些,你应该就知道chunks()的作用了!

本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。

查看目录

目录

来自 《django 不使用imagefield 实现多图上传(大容量图片2.5MB以上)》

评论区


1 条评论

  1. yyu
    2020年10月08日



可能感兴趣