我正在使用 Django 和 Backblaze B2 构建一个照片查看和存储网站,我计划上传很多大(文件大小)照片。我的计划是使用缩略图进行照片浏览,这些需要自动生成。照片上传到 Django,然后 Django 将照片上传到 B2,然后再次下载,创建缩略图并将缩略图上传到 B2。下载全尺寸图像步骤对我来说似乎没有必要,因为文件已经通过 Django 网络服务器上传了。Django 不能将上传的照片保存在内存(或临时本地存储)中,构建缩略图,然后将全尺寸图像和缩略图上传到 B2 吗?我正在使用下面的代码save()在Photo模型的步骤中生成缩略图并且它可以工作。我只是在寻找一种方法来提高效率,而无需再次下载全尺寸图像。我想过在PhotoForm使用重写的save()方法中执行此操作,但我无法找到如何执行此操作。我还包含了自定义B2Storage类的代码。如果有人能给我一个我应该采取的方法,我将不胜感激。谢谢!模型/照片.pyimport osfrom io import BytesIOfrom PIL import Imagefrom django.core.files.base import ContentFilefrom django.db import modelsfrom fotoplatform.storage import B2StorageTHUMB_SIZE = (400, 400)class Photo(models.Model): title = models.CharField(max_length=50) photo = models.ImageField(storage=B2Storage(), unique=True) thumbnail = models.ImageField(storage=B2Storage(), unique=True) def save(self, *args, **kwargs): if not self.thumbnail: self.make_thumbnail() super(Photo, self).save(*args, **kwargs) def make_thumbnail(self): try: image = Image.open(self.photo) except: raise Exception('Unable to open photo') image.thumbnail(THUMB_SIZE, Image.ANTIALIAS) thumb_name, thumb_extension = os.path.splitext(self.photo.name) thumb_extension = thumb_extension.lower() thumb_filename = thumb_name + '_thumb' + thumb_extension if thumb_extension in ['.jpg', '.jpeg']: FTYPE = 'JPEG' elif thumb_extension == '.gif': FTYPE = 'GIF' elif thumb_extension == '.png': FTYPE = 'PNG' else: raise Exception("Unknown extension") temp_thumb = BytesIO() image.save(temp_thumb, FTYPE) temp_thumb.seek(0) self.thumbnail.save(thumb_filename, ContentFile(temp_thumb.read()), save=True) temp_thumb.close()
1 回答
素胚勾勒不出你
TA贡献1827条经验 获得超9个赞
与此同时,我为此想出了一个合理的解决方案。我正在创建一个TempPhoto
包含照片文件和其他数据的对象,我想用它来存储。我将照片存储在运行 Django 的服务器上的一个temp_photos
文件夹中。然后我在TempPhoto
创建对象后调用 Celery 任务并向上传浏览器返回成功响应。
Celery 任务同时开始在后台运行,这会创建一个真实的Photo
对象,并使用make_thumbnail(self)
我的问题中描述的方法生成所需的缩略图。然后它将所有需要的东西上传到 B2。使用 Backblaze B2 的有时缓慢的 API,每张照片最多可能需要 1 分钟,但这并不重要,因为它现在在后台异步运行,独立于 Django 网络服务器。在此任务结束时,TempPhoto
对象将被删除,并且本地存储的照片temp_photo
也将被删除。
我正在寻找一种将任务进度传递回最终用户的方法,但这现在不是太重要。
添加回答
举报
0/150
提交
取消