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

The spec '<imagekit.specs.DynamicSpec object at 0x10db77110>' has no source file associated with it. #339

Open davemerwin opened 9 years ago

davemerwin commented 9 years ago

I've never seen this issue before. The issue is coming up whenI try to call a cached file from a template.

My model fields:

image = models.ImageField(upload_to='fly_image', help_text="Add a picture of a fly", blank=True, null=True)
list_display_image = ImageSpecField(source='image', processors=[Transpose(),SmartResize(720, 720)], format='JPEG', options={'quality':40})
detail_display_image = ImageSpecField(source='image', processors=[Transpose(),ResizeToFit(1200, 1200, upscale=None)], format='JPEG', options={'quality':40})

The template variable:

{{ object.list_display_image.url }}

Any ideas?

marcoacierno commented 9 years ago

When the field 'list_display_image' doesn't have an image it will raise this error. My solution so far is to just create a wrapper around it. Call a function instead of the image.url directly, catch it and return a dummy/null image if it fails.

andrewyoung1991 commented 8 years ago

+1 i'm having this issue for the first time today.

Dim4n commented 8 years ago

{% if object.image %} {{ object.list_display_image.url }} {% endif %} I think it'll work...

dezoito commented 8 years ago

I ended up using a default image in the model definition:

    image = models.ImageField(
        _("Image"),
        upload_to='uploads',
        blank=True,
        default="default.png")

That way I don't need to check if an image was set.

stunaz commented 8 years ago

can't believe this is an issue, why it is not simply returning None

vstoykov commented 8 years ago

@stunaz Actually with Django if you acces url attribute if FieldFile object that is None it also raises an Exception

ValueError: The 'file' attribute has no file associated with it.

And this is the better way instead of returning None (we write in Python not in PHP).

For some reason the exception thrown from imagekit is not silenced by the template system as the exception thrown by the Django itself.

We need to check why this is happening and to change the behavior to match the Django's FieldFile. Untill then a workaround shown by @Dim4n (https://github.com/matthewwithanm/django-imagekit/issues/339#issuecomment-199787668) must be used.

stunaz commented 8 years ago

@vstoykov Yeah, you right, it should throw an exception, I am using it in django-rest-framework. In my serializer I just realize that I am trying directly to access the url attribute.

BojanKogoj commented 7 years ago

Since this issue persists, this is my workaround (image is not defined in serializer!)

def to_representation(self, instance):
        data = super(ExampleSerializer, self).to_representation(instance)
        data['image'] = instance.image.url if instance.image.name else None
BojanKogoj commented 7 years ago

I know it's not a good solution, but another hack

class ImageMixin(object):
    """
    Get image if it exists
    """
    def get_image(self):
        return self.image.url if self.image.name else None

And use in your model

class MyModel(models.Model, ImageMixin):

That way you can use the following in serializer

def to_representation(self, instance):
  data = super(ExampleSerializer, self).to_representation(instance)
  data['image'] = instance.get_image()

You can even use it in fields tuple

Wtower commented 7 years ago

+1 subscribing.

kumar-student commented 1 year ago

I managed to make it work with below code

models.py

from imagekit.models import ImageSpecField
from imagekit.processors import ResizeToFill, TrimBorderColor

class User(AbstractUser):
    avatar = models.ImageField(upload_to='images/avatar/',  null=True, blank=True)
    avatar_thumbnail = ImageSpecField(source='avatar',
                                      processors=[ResizeToFill(100, 100),],
                                      format='JPEG',
                                      options={'quality': 60})

serializers.py

from rest_framework import serializers
from django.contrib.auth import get_user_model

User = get_user_model()

class UserSerializer(serializers.ModelSerializer):
    avatar_thumbnail = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = ('id', 'username', 'avatar', 'avatar_thumbnail')

    def get_avatar_thumbnail(self, obj):
        if obj.avatar_thumbnail:
            return obj.avatar_thumbnail.url
        return None