0

at my models.py i got a class named Post with and ImageField called postcover. I want to save every image in PNG format which is working fine so far but i have no idea how i could keep the actual image aspectio ratio after processing the image.

with the following solution i get the following error:

'int' object is not subscriptable

models.py

class Post(models.Model):
...
postcover = fields.ImageField(
        verbose_name="Post Cover",
        blank=True,
        null=True,
        upload_to=get_file_path_user_uploads,
        validators=[default_image_size, default_image_file_extension]
    )
...
def save(self, *args, **kwargs):
    super(Post, self).save(*args, **kwargs)
    if self.postcover:
        if os.path.exists(self.postcover.path):
            imageTemproary = Image.open(self.postcover)
            outputIoStream = BytesIO()
            baseheight = 500
            hpercent = (baseheight / float(self.postcover.size[1]))
            wsize = int((float(self.postcover.size[0]) * float(hpercent)))
            imageTemproaryResized = imageTemproary.resize((wsize, baseheight))
            imageTemproaryResized.save(outputIoStream, format='PNG')
            outputIoStream.seek(0)
            self.postcover = InMemoryUploadedFile(outputIoStream, 'ImageField',
                                                  "%s.png" % self.postcover.name.split('.')[0], 'image/png',
                                                  sys.getsizeof(outputIoStream), None)
    super(Post, self).save(*args, **kwargs)

full trace:

 Internal Server Error: /post/2/edit/
 Traceback (most recent call last):
   File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
     response = get_response(request)
   File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
     response = self.process_exception_by_middleware(e, request)
   File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 124, in _get_response
     response = wrapped_callback(request, *callback_args, **callback_kwargs)
   File "/app/app_Accounts/decorators.py", line 33, in _wrapped_view
     return view_func(request, *args, **kwargs)
   File "/usr/local/lib/python3.6/site-packages/ratelimit/decorators.py", line 30, in _wrapped
     return fn(*args, **kw)
   File "/app/app/views.py", line 473, in post_edit
     post.save()
   File "/app/app/models.py", line 204, in save
     hpercent = (baseheight / float(self.postcover.size[1]))
 TypeError: 'int' object is not subscriptable

Thanks for help in advance :)

5
  • Please include the full traceback of the exception; in the web view there is a 'text only' link for this. Commented Apr 2, 2019 at 21:14
  • And what is self.postcover here? Is it a file object? If so, then .size can't be an image size (tuple with width and height), perhaps you meant to use imageTemproary.size instead? Commented Apr 2, 2019 at 21:16
  • Just added the full trace Commented Apr 2, 2019 at 21:18
  • And yes it is a file object Commented Apr 2, 2019 at 21:32
  • Then self.postcover.size is not a tuple. That's the file size in bytes. Use imageTemproary.size. Commented Apr 2, 2019 at 21:50

1 Answer 1

1

You are trying to treat the file size as a tuple with width and height. You want to use imageTemproary.size instead, not self.postcover.size:

hpercent = baseheight / imageTemproary.size[1]
wsize = int(imageTemproary.size[0] * hpercent)

I've simplified the code too, you are using Python 3, where / produces a float value even if the inputs are both integers (true division, not floor division).

You may want to correct the spelling of the image object variable (imageTemporary); personally I'd just use image.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.