sorl-thumbnail
sorl-thumbnail copied to clipboard
No way to address issues with images provided to get_thumbnail()
sorl-thumbnail
does not provide any way to catch and address errors when attempting to read invalid images using get_thumbnail()
. I noticed that the project has a THUMBNAIL_DEBUG
setting to address this problem, but it appears to only apply to template tags and not when using the low-level API directly.
Here is my specific use case: I have a Django REST Framework serializer for users that contains a photo
field which produces a URL to a thumbnail of the user's photo. Here is the current code:
from django.contrib.staticfiles.storage import staticfiles_storage
from rest_framework import serializers
from sorl.thumbnail import get_thumbnail
class UserSerializer(serializers.ModelSerializer):
photo = serializers.SerializerMethodField("get_photo_url")
class Meta:
model = User
fields = ("first_name", "last_name", "photo")
def get_photo_url(self, obj):
try:
photo = obj.photo
except Photo.DoesNotExist:
return staticfiles_storage.url("img/person-outline.png")
else:
# broken images cause errors to be logged, but those errors are not propagated here
thumbnail = get_thumbnail(photo.img, "135x135", crop="center")
return self.context["request"].build_absolute_uri(thumbnail.url)
If there is something wrong with the image provided to get_thumbnail()
, perhaps it doesn't exist or cannot be read as an image, that exception is not propagated here. Instead, errors are logged and a dummy thumbnail is used instead.
I'd like to detect when this happens so that I can I can provide a static image instead, as you can see I am doing when the Photo
instance for the user does not exist (ie. the user has never uploaded a photo). I could use the THUMBNAIL_DUMMY_SOURCE
setting to achieve this, but that is a global setting and I have a similar paradigm when serializing other types of objects other than users. I don't want to share the same thumbnail for each of these cases, I want a different thumbnail for each type.
The only solution I can think of that I could apply right now would be to always inspect the image file before providing it to get_thumbnail()
, but obviously this is very inefficient.
If THUMBNAIL_DEBUG
was changed to apply when using the low-level API, this would solve my problem, but honestly it wouldn't be an ideal solution. I'd rather not raise errors across the entire application, but instead I think it would be better to be able to opt into raising errors in specific contexts. For instance, a kwarg raise_errors
could be added to get_thumbnail()
:
try:
thumbnail = get_thumbnail(photo.img, "135x135", raise_errors=True, crop="center")
except IOError:
... # handle invalid file
Does this request make sense? Have I missed anything? Perhaps there is a feature in sorl-thumbnail
I am not aware of that satisfies my use case? Regardless, thank you very much for reading. I appreciate your time.
In my case, this was the error message if I called the get_thumbnail function: 'NoneType' object has no attribute 'build_absolute_uri'
The error's reason: There was no request object in the serializer's context dictionary.
The solution:
In the View, I call the serializer with
serializer = TheSerializer(instance, data=data, context=self.get_serializer_context())
or
serializer = TheSerializer(instance, data=data, context={'request': request})
I hope this will help to somebody :)