Reputation: 337
My Django app generates a file. It takes img1.png
and watermark.png
and past them together and saves it again in the folder.
Everything works as expected.
This is the function:
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')
When working locally on my computer everything is good with specifying the path. However, in production it does not work anymore. I need to save the generatedfile.png
directly on AWS S3.
For this reason I have create a simple model:
class pngUploadModel(models.Model):
auto_increment_id = models.AutoField(primary_key=True, default=True)
image = models.ImageField(null=True, blank=True, upload_to="png/")
I am able to upload images to this model using the admin interface. Everything still works as expected.
Now to my struggle. I need to generate the image, and saving it "directly" to the model. Without saving it first to the path (because this will not work in production).
Approach:
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}')
Output: It creates an object in my model which I can see on my admin panel, but the model is empty, there is no image.
How can I save the generated image to my model, without having to save it first to my local directory. I was thinking to use something like a tempfile
but I do not know if it is the right way.
Upvotes: 0
Views: 395
Reputation: 1370
If I'm correct, you want to get the generated file from the file path (f'{current_path}/media/pdf/generatedfile.png'
) and save it to your pngUploadModel
.
An approach that I remember taking recently was to use the same prefix of the generated filename, setting that to be where the model instance image field points. For example:
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}')
I used this answer as my guide then and it worked perfectly.
Another way is to save the generated file to the image field by passing a few arguments to the save()
on the image/file field. Example:
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()
Ideally, that should work. You can also view other answers to this question as they might be helpful or can be used for future reference.
Upvotes: 1