Maverick
Maverick

Reputation: 2760

Django QR code generation PIL image saving using S3 not working

I am trying to generate QR code based on model. I am hosting the app at Heroku and using AWS S3 as sotrage. Storage with S3 works totally fine with other model elements, just the model for QR code generation is giving trouble. I am using this link as reference: https://gilang.chandrasa.com/blog/generate-qr-code-in-django-model/ My model is:

class BusinessQRCode(models.Model):
    business = models.ForeignKey(Business, null=True)
    location_name = models.CharField(max_length=255)
    qrcode = models.ImageField(upload_to='documents/{}'.format(time.strftime("%Y/%m/%d")), blank=True, null=True)

    def save(self):
        super(BusinessQRCode, self).save()
        self.generate_qrcode()

    def generate_qrcode(self):
        from activation.models import RandomFileName

        qr = qrcode.QRCode(
            version=1,
            error_correction=qrcode.constants.ERROR_CORRECT_L,
            box_size=10,
            border=4,
        )
        qr.add_data('Some data')
        qr.make(fit=True)

        filename = 'qrcode-%s.png' % self.id

        img = qr.make_image()

        from django.conf import settings
        img.save(settings.MEDIA_ROOT + filename)

        # reopen = open(settings.MEDIA_ROOT + filename, "rb")
        # django_file = File(reopen)
        self.qrcode.save(filename,img, save=True)

The above code gives me this error:

TypeError

TypeError: seek() takes exactly 2 arguments (3 given)

I have tried using the commented code as well, that is opening the file and than trying to save it, but it doesnt work, it just never stops loading. What I mean is this part of the code in the end:

reopen = open(settings.MEDIA_ROOT + filename, "rb")
django_file = File(reopen)
self.qrcode.save(filename,django_file, save=True)

What am I doing wrong?

Upvotes: 1

Views: 2808

Answers (1)

Håken Lid
Håken Lid

Reputation: 23064

I have tried using the commented code as well, that is opening the file and than trying to save it, but it doesnt work, it just never stops loading.

I think the last approach should work, but since you use save=True when saving the ImageField, that will trigger the parent model's save() method as well. So you will end up in an infinite loop.

Change the order you save the imagefield and the model.

def save(self):
    # Generate qrcode before calling super.save
    self.generate_qrcode() 
    super(BusinessQRCode, self).save()

def generate_qrcode(self):

    ...

    with open(settings.MEDIA_ROOT + filename, "rb") as reopen:
        django_file = File(reopen)
        self.qrcode.save(filename,django_file, save=False)

Upvotes: 3

Related Questions