У меня есть модель, которая принимает файл для загрузки. Мне нужно выполнить некоторую обработку файла перед его сохранением: 1. создать миниатюру изображения и сохранить его в другом файловом поле 2. создать изображение определенного размера и типа и сохранить это изображение в другом файловом поле 3. при необходимости сохранить исходное изображение в третьем поле файла
Я выполнил 1 и 2, но не 3, и получил неожиданный результат.
Моя модель:
class Document(Model):
document_id = models.AutoField(primary_key=True)
storage_file_name = models.FileField('File name', upload_to=unique_file_path_2)
thumb_file = models.FileField("thumb", upload_to=settings.DOCUMENT_FOLDER_THUMB, default=settings.DEFAULT_THUMBNAIL)
xxxlarge_file = models.FileField('xxxlarge', upload_to=settings.DOCUMENT_FOLDER_XXXLARGE, default=settings.DEFAULT_THUMBNAIL)
и функция upload_to:
def unique_file_path_2(instance, filename):
temp_image = BytesIO()
image = None
default_thumb = None
default_file = None
f = None
try:
#fred = 3/0 # to test the exception path
pages = wImage(blob = instance.storage_file_name)
first_page = pages.sequence[0]
image = wImage(first_page)
image.transform(resize=settings.DOCUMENT_XXXLARGE_WIDTH.split("px")[0])
image.format = "png"
image.save(temp_image)
temp_image.seek(0)
file_name, extension = os.path.splitext(filename)
instance.xxxlarge_file.save(file_name + ".png", ContentFile(temp_image.read()), save=False)
# make a thumbnail
image_processing_utils.make_thumb(instance, filename)
except:
# save default images instead of the uploaded image
logger.exception("unique_file_path_2 Exception")
default_image = settings.DEFAULT_IMAGE_NAME.replace("size", "xxxlarge")
default_image_path = os.path.join(settings.DEFAULT_IMAGE_PATH, default_image)
f = open(default_image_path, 'r+b')
default_file = File(f)
instance.xxxlarge_file.save(default_image, default_file, save=False)
f = open(settings.DEFAULT_THUMBNAIL, 'r+b')
default_thumb = File(f)
thumb_name, thumb_extension = os.path.splitext(filename)
thumb_extension = ".jpg"
thumb_name = thumb_name + thumb_extension
instance.thumb_file.save(thumb_name, default_thumb, save=False)
finally:
if image:
image.close
if temp_image:
temp_image.close
if default_thumb:
default_thumb.close
if default_file:
default_file.close
if f:
f.close
return "originals/" + filename
Миниатюра создается правильно, размер изображения корректно изменяется, преобразуется в формат png и помещается в местоположение xxxlarge. Тем не менее, я получаю два файла в папке originals /: исходный tiff и tiff, преобразованный в png, но в его исходном размере.
Это моя структура файла MEDIA_ ROOT после загрузки Test.tiff:
.
├── originals
│ ├── Test.png
│ └── Test.tiff
├── thumb
│ └── Test.jpg
└── xxxlarge
└── Test.png
У меня следующие вопросы:
- Это лучший способ выполнить sh то, что я хочу? Должен ли я сделать это в модели save () или написать свою собственную функцию хранения бэкэнда? Я видел примеры использования всех этих трех методов для изменения загруженного файла в django.
- . Я не уверен, почему я получаю изображения png и tiff в папке оригиналов. Оба имеют тот же размер, что и оригинальное изображение. Изображение png в папке xxxlarge / соответствует размеру, который должен быть. Миниатюра в большом пальце / папке тоже имеет правильный размер.
- Как предотвратить сохранение исходного загруженного изображения на основе настроек в base.py? Например, если для settings.SAVE_ORIGINAL_DOCUMENT установлено значение True, загруженное изображение должно быть сохранено в папке оригиналов /. Если False, то ничего не следует сохранять в папке оригиналов /, но я все еще хочу, чтобы изображение правильного размера и конвертировалось в папку xxxlarge / и в папку thumb /.
Спасибо!
Mark