Django генерирует файл и сохраняет его в модели
Мое приложение Django генерирует файл. Оно берет img1.png
и watermark.png
, вставляет их вместе и снова сохраняет в папке.
Все работает так, как ожидалось.
Это функция:
def generate():
img1 = Image.open(f'{current_path}/media/pdf/img1.png')
img2 = Image.open(f'{current_path}/media/watermark.png')
img1.paste(img2, (150, 250), img2)
img1.save(f'{current_path}/media/pdf/generatedfile.png')
При локальной работе на моем компьютере все хорошо с указанием пути. Однако в продакшене это больше не работает. Мне нужно сохранить generatedfile.png
непосредственно на AWS S3.
Для этого я создал простую модель:
class pngUploadModel(models.Model):
auto_increment_id = models.AutoField(primary_key=True, default=True)
image = models.ImageField(null=True, blank=True, upload_to="png/")
Я могу загружать изображения в эту модель с помощью интерфейса администратора. Все работает, как и ожидалось.
Теперь перейдем к моей проблеме. Мне нужно сгенерировать изображение и сохранить его "напрямую" в модель. Не сохраняя его сначала в путь (потому что это не будет работать в производстве).
Подход:
def generate():
img1 = Image.open(f'{current_path}/media/pdf/img1.png')
img2 = Image.open(f'{current_path}/media/watermark.png')
img1.paste(img2, (150, 250), img2)
img1.save(f'{current_path}/media/pdf/generatedfile.png')
try:
filename = pngUploadModel.objects.create()
filename.image = img2
print('worked!')
except Exception as e:
print(f'this is the error message: {e}')
Вывод: Он создает объект в моей модели, который я могу видеть на моей панели администратора, но модель пуста, там нет изображения.
Как я могу сохранить сгенерированное изображение в моей модели, не сохраняя его сначала в локальной директории. Я думал использовать что-то вроде tempfile
, но не знаю, правильный ли это способ.
Если я правильно понял, вы хотите получить сгенерированный файл из пути к файлу (f'{current_path}/media/pdf/generatedfile.png'
) и сохранить его в вашем pngUploadModel
.
Подход, который я помню, недавно использовал, заключался в использовании того же префикса сгенерированного имени файла, устанавливая его в то место, куда указывает поле изображения экземпляра модели. Например:
def generate():
img1 = Image.open(f'{current_path}/media/pdf/img1.png')
img2 = Image.open(f'{current_path}/media/watermark.png')
img1.paste(img2, (150, 250), img2)
img1.save(f'{current_path}/media/pdf/generatedfile.png')
# the prefix string of the generated file -> f'{current_path}/media/pdf/generatedfile.png'
try:
genFile = pngUploadModel()
# Using the path/prefix of the generated file to be set to the image field
genFile.image = f'{current_path}/media/pdf/generatedfile.png'
genFile.save()
print('worked!')
except Exception as e:
print(f'this is the error message: {e}')
Я использовал этот ответ в качестве руководства, и он отлично сработал.
Другой способ - сохранить сгенерированный файл в поле image, передав несколько аргументов в save()
на поле image/file. Пример:
from django.core.files.base import ContentFile # ensure you import
def generate():
prefix = f'{current_path}/media/pdf/generatedfile.png'
img1 = Image.open(f'{current_path}/media/pdf/img1.png')
img2 = Image.open(f'{current_path}/media/watermark.png')
img1.paste(img2, (150, 250), img2)
img1.save(prefix)
# the prefix string of the generated file -> f'{current_path}/media/pdf/generatedfile.png'
# with open('/path/to/already/existing/file', 'rb') as f:
with open(prefix, 'rb') as f:
data = f.read()
genFile = pngUploadModel()
genFile.image.save('generatedfile.png', ContentFile(data))
genFile.save()
Идеально, это должно сработать. Вы также можете просмотреть другие ответы на этот вопрос, так как они могут быть полезны или могут быть использованы в будущем.