姜戈 |提供两个上传的图像版本——WebP 和 JPEG

Django | Serve two uploaded images version - WebP and JPEG

我只想问你一个最佳实践,如何通过 Django 向用户提供 WebP 和 JPEG 图像。

我有一个关于车辆的网站 - 每天添加大约 1 000 辆车,每辆车大约有 10 张图片。那是很多图像。我做了一个自定义的“import django-admin command”,它解析了一个车辆:

  1. 它从源下载 JPEG 图片(一辆车 10 张图片)
  2. 然后为所有下载的图像应用水印
  3. 之后,这张图片被转换为WebP格式并通过Django save()上传到Images table,它有一个Vehicle的ForeignKey(我是为此使用 ImageField)
  4. 然后它压缩原始 JPEG 图像,并通过 shutil.move 将这些压缩的 JPEG 图像移动到存储 WebP 图像格式的同一文件夹中。

因为我使用的是 AMP HTML,我可以简单地从 WebP 回退到不支持 WebP 的浏览器的 JPEG。而且因为图像在同一个 /media/.../ 文件夹中,所以它工作得很好。

但是今天我发现,这个方法并不完美。当有相同的图片名称时,Django 在 save() 方法 get_random_string() 方法中,会额外生成 7 个字符文件结尾 https://github.com/django/django/blob/master/django/utils/crypto.py

所以我的shuitl.move()方法失败了:

shutil.Error: Destination path '/home/django/exampleproject/media/2020/12/10/example-compressed-image-img01.jpg' already exists

而且我不知道,如何弄清楚,如何为这个 JPEG 文件获取相同的名称 - 如何在文件末尾获取这个散列。文件名必须相同 - 对于 WebP 和 JPEG,唯一的扩展名必须不同。 当然,我可以列出所有文件,找到那些哈希值并尝试附加它们...但我认为,这种方法并不完美。

最好的方法是只使用 WebP 图片,但并非所有浏览器都支持它。由于 SEO,使用 WebP 对我来说真的很重要 - 它在文件名中有关键字。

有没有更好的方法,如何将ImageField中的WebP和JPEG图片保存到同一个upload_to目录下,同名(也是Django会重命名的时候)它在文件名已经存在时)?我不想为那个或两个列使用两个 tables,因为它是很多字符串,如果我将来有 10M+ 记录,那是数据库中的大量数据。

我很乐意提供任何建议,谢谢!

我通过在文件名中插入一个 uuid 解决了一个类似的问题。这是一个例子。 Enforce unique upload file names using django?

另一种选择是上传到 S3,它会根据需要自动创建唯一的文件名,然后 运行 针对新上传的 lambda 函数生成第二个图像和文件名。