matthewwithanm / django-imagekit

Automated image processing for Django. Currently v4.0
http://django-imagekit.rtfd.org/
BSD 3-Clause "New" or "Revised" License
2.27k stars 275 forks source link

Integration with django-parler package #570

Open mirodil1 opened 7 months ago

mirodil1 commented 7 months ago

I have multilanguage app, and I need to use multiple images in different languages, I am using django-parler for that, but django-imagekit is generating images. models.py

class Slider(models.Model):
    translations = TranslatedFields(
        image = models.ImageField(upload_to="slider"),
        image_large = ImageSpecField(source="image", processors=[ResizeToFill(1216,388)], format="webp", options={"quality": 90}),
        image_medium = ImageSpecField(source="image", processors=[ResizeToFill(728,410)], format="webp", options={"quality": 90})
    )
    is_active = models.BooleanField(default=False)

I've tried another option like:

class Slider(models.Model):
    translations = TranslatedFields(
        image = models.ImageField(upload_to="slider"),
    )
    image_large = ImageSpecField(source="translations__image", processors=[ResizeToFill(1216,388)], format="webp", options={"quality": 90})
    image_medium = ImageSpecField(source="translations__image", processors=[ResizeToFill(728,410)], format="webp", options={"quality": 90})
   is_active = models.BooleanField(default=False)

None of them worked. Is it possible to use it with django-parler?

mirodil1 commented 7 months ago

I tried something in signals.py, if I call image field it saves image: signals.py

@receiver(post_save, sender=Slider)
def save_image(sender, instance, created, **kwargs):
    translations = instance.translations.all()
    for translation in translations:
        translation.image_medium.url
        translation.image_large.url

In this case images are being saved sometimes.

vstoykov commented 6 months ago

The first variant is probably not working because the ImageSpecFields are not columns in the DB (I'm speculating here). The second option though at first sounds like it should work but without actual error why it failed I can't say anything. I've never tested django-imagekit in django-parler together.

Based on your feedback we can investigate if this is some bug in django-imagekit or is something specific to django-parler and how the integration with it should happen. Please share more details (like traceback) or what exactly you mean by "None of them worked."

mirodil1 commented 6 months ago

Please share more details (like traceback) or what exactly you mean by "None of them worked."

I meant both variants didn't work, and I am not getting any error. What I've achieved so far, used first variant (model), If I use second variant, it cannot find source image field:

class Slider(models.Model):
    translations = TranslatedFields(
        image = models.ImageField(upload_to="slider"),
        image_large = ImageSpecField(source="image", processors=[ResizeToFill(1216,388)], format="webp", options={"quality": 90}),
        image_medium = ImageSpecField(source="image", processors=[ResizeToFill(728,410)], format="webp", options={"quality": 90})
    )
    is_active = models.BooleanField(default=False)

serializers.py

class SliderSerializer(TranslatedSerializerMixin, TranslatableModelSerializer):
    translations = TranslatedFieldsField()
    image_large = serializers.SerializerMethodField()
    image_medium = serializers.SerializerMethodField()

    class Meta:
        model = Slider
        fields = [
            "id",
            "translations",
            "image_large",
            "image_medium",
        ]

     def get_image_large(self, obj):
         lang = obj.get_current_language()
         translation = obj.translations.get(language_code=lang)
         return translation.image_large.url

     def get_image_medium(self, obj):
         lang = obj.get_current_language()
         translation = obj.translations.get(language_code=lang)
         return translation.image_medium.url

In this case when request to api, it returns images without any problem. In my opinion, images are being generated while creating object but not saving them, if I make a request to this api, images are suddenly being appeared in media folder.

vstoykov commented 6 months ago

In my opinion, images are being generated while creating object but not saving them, if I make a request to this api, images are suddenly being appeared in media folder.

This is how django-imagekit is designed to work when ImageSpecField is used. There are no columns in the DB to store the path/URL of the thumbnail. When the code is wanting to obtain the url of the thumbnail, based on the source and processors and the cachefile namers the URL is generated. Based on the cachefile backend configured the actual thumbnail file can be generated immediately or asynchronously.

Now based on that and your findings can we assume that there is no issue and we can close it?

mirodil1 commented 6 months ago

There are no columns in the DB to store the path/URL of the thumbnail.

Yes I understand that, but in normal use when object saved it generates image and also saves image, it appears in media folder, and also I was able to use it as object atrtribute to get image, serializer also knows it as field.

Now based on that and your findings can we assume that there is no issue and we can close it?

It is working, but I don't think it is the good way to make it work, in serializer images should come inside translations = TranslatedFieldsField() without defining any methods or fields separately. It's better if You test it by yourself to understand the problem better.

vstoykov commented 6 months ago

It's better if You test it by yourself to understand the problem better.

Sorry for that but currently I'm mostly reviewing PRs and releasing new versions. I don't have the free time to debug issues for others. If you can propose better integration with django-parler I'll be happy to review and merge.