Python 图像缩略图Django Backblaze B2
我正在使用Django和Backblaze B2构建一个照片查看和存储网站,我有很多大文件大小的照片,我计划上传到上面 我的计划是使用缩略图浏览照片,这些需要自动生成。照片上传到Django,Django将照片上传到B2,然后再次下载,创建缩略图并将缩略图上传到B2 下载全尺寸图像步骤对我来说似乎没有必要,因为文件已经通过Django Web服务器上传。Django难道不能将上传的照片保存在内存或临时本地存储中,构建一个缩略图,然后将全尺寸图像和缩略图都上传到B2吗 我正在使用下面的代码在照片模型的保存步骤中生成一个缩略图,它可以正常工作。我只是在寻找一种方法,使这更有效,而无需再次下载全尺寸图像。我曾想过在PhotoForm中使用一个重写的save方法来实现这一点,但我找不到如何实现这一点。我还包括了自定义存储类的代码 如果有人能给我一个我应该采取的方法,我将不胜感激。谢谢 models/photo.py forms.py 存储空间.pyPython 图像缩略图Django Backblaze B2,python,django,Python,Django,我正在使用Django和Backblaze B2构建一个照片查看和存储网站,我有很多大文件大小的照片,我计划上传到上面 我的计划是使用缩略图浏览照片,这些需要自动生成。照片上传到Django,Django将照片上传到B2,然后再次下载,创建缩略图并将缩略图上传到B2 下载全尺寸图像步骤对我来说似乎没有必要,因为文件已经通过Django Web服务器上传。Django难道不能将上传的照片保存在内存或临时本地存储中,构建一个缩略图,然后将全尺寸图像和缩略图都上传到B2吗 我正在使用下面的代码在照片模
与此同时,我已经想出了一个合理的解决办法。我正在创建一个TempPhoto对象,其中包含照片文件和其他我想与之一起存储的数据。我将照片存储在运行Django的服务器上的temp_photos文件夹中。然后在创建TempPhoto对象后调用芹菜任务,并向上传浏览器返回成功响应 同时芹菜任务开始在后台运行,这将创建一个真实的照片对象,并使用问题中描述的make_thumbnailself方法生成所需的缩略图。然后它将所有需要的东西上传到B2。Backblaze B2的API有时速度很慢,因此每张照片最多需要1分钟,但这并不重要,因为它现在在后台异步运行,与Django Web服务器无关。此任务结束时,删除TempPhoto对象,并删除temp_photo中本地存储的照片 我正在寻找一种将任务进度反馈给最终用户的方法,但目前这并不太重要
import os
from io import BytesIO
from PIL import Image
from django.core.files.base import ContentFile
from django.db import models
from fotoplatform.storage import B2Storage
THUMB_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()
import logging
from django import forms
from fotoplatform.models import Photo
class PhotoForm(LoggingMixin, forms.ModelForm):
photo = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))
class Meta:
model = Photo
fields = ['title', 'photo']
import hashlib
import logging
import os
import re
from b2blaze import B2
from django.core.files.storage import Storage
from django.utils.deconstruct import deconstructible
from dsbfotoplatform import settings
logger = logging.getLogger(__name__)
b2 = B2(key_id=settings.B2_KEY_ID, application_key=settings.B2_APPLICATION_KEY)
bucket = b2.buckets.get(bucket_id=settings.B2_BUCKET_ID)
@deconstructible
class B2Storage(Storage):
def path(self, name):
pass
def delete(self, name):
pass
def exists(self, name):
pass
def listdir(self, path):
pass
def size(self, name):
pass
def get_accessed_time(self, name):
pass
def get_created_time(self, name):
pass
def get_modified_time(self, name):
pass
def _open(self, name, mode='rb'):
file = bucket.files.get(file_name=name)
return file.download()
def _save(self, name, content):
name = self.generate_filename(name)
name = "photos/" + name
bucket.files.upload(contents=content, file_name=name)
return name
def generate_filename(self, filename):
filename, file_extension = os.path.splitext(filename)
m = hashlib.md5()
m.update(filename.encode("UTF-8"))
return m.hexdigest() + file_extension
def url(self, name):
url = re.sub(r'b2api.*$', '', bucket.connector.download_url)
url += "fotoplatform/" + name
return url