SmileyChris / easy-thumbnails

Easy thumbnails for Django
http://easy-thumbnails.readthedocs.org/
BSD 3-Clause "New" or "Revised" License
1.37k stars 312 forks source link

Django Rest Framework : InvalidImageFormatError with Django File #549

Open nico-dfg opened 3 years ago

nico-dfg commented 3 years ago

I am using Django Rest Framework to upload profile picture and easy-thumbnails to resize my images. I test my API and I have this result :

File "/home/worldorama/profile/views.py", line 84, in post profile_picture = services.upload_profile_picture( File "/home/worldorama/profile/services.py", line 225, in upload_profile_picture return ProfilePicture.objects.create( File "/usr/local/lib/python3.8/site-packages/django/db/models/manager.py", line 82, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "/usr/local/lib/python3.8/site-packages/django/db/models/query.py", line 422, in create obj.save(force_insert=True, using=self.db) File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 740, in save self.save_base(using=using, force_insert=force_insert, File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 777, in save_base updated = self._save_table( File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 870, in _save_table result = self._do_insert(cls._base_manager, using, fields, update_pk, raw) File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 907, in _do_insert return manager._insert([self], fields=fields, return_id=update_pk, File "/usr/local/lib/python3.8/site-packages/django/db/models/manager.py", line 82, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "/usr/local/lib/python3.8/site-packages/django/db/models/query.py", line 1186, in _insert return query.get_compiler(using=using).execute_sql(return_id) File "/usr/local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1374, in execute_sql for sql, params in self.as_sql(): File "/usr/local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1316, in as_sql value_rows = [ File "/usr/local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1317, in <listcomp> [self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields] File "/usr/local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1317, in <listcomp> [self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields] File "/usr/local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1268, in pre_save_val return field.pre_save(obj, add=True) File "/usr/local/lib/python3.8/site-packages/django/db/models/fields/files.py", line 288, in pre_save file.save(file.name, file.file, save=False) File "/usr/local/lib/python3.8/site-packages/easy_thumbnails/files.py", line 759, in save content = Thumbnailer(content, name).generate_thumbnail(options) File "/usr/local/lib/python3.8/site-packages/easy_thumbnails/files.py", line 385, in generate_thumbnail raise exceptions.InvalidImageFormatError( easy_thumbnails.exceptions.InvalidImageFormatError: The source file does not appear to be an image

I do not understand why this exception is raised because I have tested with multiple correct jpeg images. The Django file works correctly with Django ImageField when I create object but not with ThumbnailerImageField.

Here is my code : Model : `class ProfilePicture(models.Model): user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="profile_pictures", null=True, blank=True, ) original = models.ImageField( upload_to="profile_pictures_original", default="", null=False, blank=False, ) small = ThumbnailerImageField( upload_to="profile_pictures_small", resize_source=dict(size=(300, 300), sharpen=True), default="", null=False, blank=True, )

def __str__(self):
    return self.original.url``

View : `class UploadProfilePictureAPI(APIView): permission_classes = (IsAuthenticated,) parser_classes = (MultiPartParser,) @staticmethod def post(request): input_serializer = serializers.UploadProfilePictureSerializer(data=request.data) input_serializer.is_valid(raise_exception=True)

    profile_picture = services.upload_profile_picture(
        request.user, **input_serializer.validated_data
    )

    output_serializer = serializers.ProfilePictureSerializer(profile_picture)
    return Response(output_serializer.data, status=status.HTTP_202_ACCEPTED)`

Serializer: class UploadProfilePictureSerializer(serializers.Serializer): profile_picture = serializers.ImageField(required=True, allow_empty_file=False)

And Service : def upload_profile_picture(user: User, profile_picture: File) -> ProfilePicture: return ProfilePicture.objects.create( user=user, original=profile_picture, small=profile_picture )

My config :

Django==2.2.11
djangorestframework==3.10.3
easy-thumbnails==2.7
Pillow==6.2.2

Thank you in advance for helping me.

nico-dfg commented 3 years ago

Nota : when I use django admin, I can upload photo without problem.

nico-dfg commented 3 years ago

Edit : I resolve the problem with this :

def upload_profile_picture(user: User, profile_picture: File) -> ProfilePicture: picture = ProfilePicture.objects.create(user=user, small=profile_picture) picture.original = profile_picture picture.save() return picture

Could anyone explain me ? Did I do it right ?