GCMeccariello
GCMeccariello

Reputation: 337

Django generate file and save it to model

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

Answers (1)

Damoiskii
Damoiskii

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

Related Questions