django-cloudinary-storage icon indicating copy to clipboard operation
django-cloudinary-storage copied to clipboard

This backend doesn't support absolute paths

Open coder-Aayush opened this issue 3 years ago • 3 comments

I was trying to upload image to cloudinary by decreasing the quality of image. I run into this error while uploading image.

Code

Models.py

class MyModel(models.Model):
      image = models.ImageField(upload_to='image/')
      .....

     def save(self, *args, **kwargs):
          instance = super(MyModel, self).save(*args, **kwargs)
          img = Image.open(self.image.path)
          img.save(self.image.path, quality=10, optimize=True)
          return instance
Logs
Traceback (most recent call last):
  File "venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/venv/lib/python3.9/site-packages/django/contrib/admin/options.py", line 614, in wrapper
    return self.admin_site.admin_view(view)(*args, **kwargs)
  File "/venv/lib/python3.9/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "venv/lib/python3.9/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/venv/lib/python3.9/site-packages/django/contrib/admin/sites.py", line 233, in inner
    return view(request, *args, **kwargs)
  File "/lib/python3.9/site-packages/django/contrib/admin/options.py", line 1653, in add_view
    return self.changeform_view(request, None, form_url, extra_context)

    return self._changeform_view(request, object_id, form_url, extra_context)
  File "/venv/lib/python3.9/site-packages/django/contrib/admin/options.py", line 1580, in _changeform_view
    self.save_model(request, new_object, form, not add)
  File "venv/lib/python3.9/site-packages/django/contrib/admin/options.py", line 1093, in save_model
    obj.save()
  File "/mymodels/models.py", line 33, in save
    img = Image.open(self.image.path)
  File "venv/lib/python3.9/site-packages/django/db/models/fields/files.py", line 57, in path
    return self.storage.path(self.name)
  File "/lib/python3.9/site-packages/django/core/files/storage.py", line 116, in path
    raise NotImplementedError("This backend doesn't support absolute paths.")

Exception Type: NotImplementedError at /admin/mymodels/add/
Exception Value: This backend doesn't support absolute paths.

coder-Aayush avatar Apr 15 '21 19:04 coder-Aayush

@coder-Aayush according to this error, probably somehow you you absolute path, which is not implemented. Could you try using relative paths?

klis87 avatar Apr 15 '21 20:04 klis87

I won't recommend saving images like this. What you are doing is, saving an image first and then accessing it to modify and save it again. A better approach would be to intercept before saving the image. You can implement such like this.

Here I have also changed the image to jpeg to save more space but it's optional.

`

from django.db import models from PIL import Image # pip install pillow from io import BytesIO from django.core.files.uploadedfile import InMemoryUploadedFile as imuf

class ImageModel(models.Model): photo = models.ImageField(upload_to='path') # photo field

def save(self, *args, **kwargs):
  	# only compress on the first save()
    if not self.id: 
        self.photo = self.compressImage(self.photo)
    # Call the original save() method
    super(ImageModel, self).save(*args, **kwargs)

def compressImage(self, uImage):
  	# Use PIL to open
    new = Image.open(uImage)
    # Convert to RGB as RGBA can not be changed into JPEG(no transparency)
    new = new.convert('RGB')
    fName = uImage.name.split('.')[0]
    outio = BytesIO()
    # Save the new file
    new.save(outio, format='JPEG', quality=30)
    uImage = imuf(outio, 'ImageField', f"{fName}.jpg", 'image/jpeg', outio.tell(), None)
	# return that file name to store in Database
    return uImage`

awebisam avatar Apr 16 '21 01:04 awebisam

@coder-Aayush according to this error, probably somehow you you absolute path, which is not implemented. Could you try using relative paths?

Can you give some code sample?

coder-Aayush avatar Apr 19 '21 10:04 coder-Aayush