I've set up django-sorl and I truly think I'm overlooking something simple. I keep getting the following error (TEMPLATE_DEBUG = True and THUMBNAIL_DEBUG = True)
Request Method: GET Request URL: http://localhost:8000/events/edit/1
Django Version: 1.2.4 Exception Type: TemplateSyntaxError Exception Value:
Caught IOError while rendering: (2, 'No such file or directory')
Exception Location: /usr/lib/python2.6/site-packages/django/core/files/storage.py in _open, line 137
Python Executable: /usr/bin/python Python Version: 2.6.4
I'm running a redis server setup... my sorl config is:
settings.py -snip-:
TEMPLATE_DEBUG = DEBUG
THUMBNAIL_DEBUG = DEBUG
THUMBNAIL_KVSTORE = 'sorl.thumbnail.kvstores.redis_kvstore.KVStore'
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'sorl.thumbnail',
)
models.py -snip-:
from sorl.thumbnail import ImageField
...
path = ImageField(
_('Image'),
upload_to='event/%Y/%m/%d/%H',
)
...
template.html -snip-:
{% load thumbnail %}
...
{% thumbnail image "200x100" as im %}
<img src="{{ im.url }}" alt="{{ im.name }}"/>
{% endthumbnail %}
...
I figure I'm close because files are being created on demand in the cache folder
sh> find static/cache/ -type f
static/cache/db/ac/dbac605942d9651eb25f16cf05f5e672.jpg
static/cache/82/bc/82bcdd2ab079187c6b6110cb0e0c1505.jpg
static/cache/07/77/077784411739d4f8b1758255783388ec.jpg
When I open these files; they are the images I'm requesting on-demand. It seems to be bombing while trying to open the image to display it. Another thing to note is that if I just display the image using the following syntax it will work fine (without sorl):
working template.html (without sorl - hence... no thumbnails) -snip-:
<img src="{{ MEDIA_URL}}{{ image.path }}" alt="{{ image.name }}"/>
The key being; that I do need to prefix the {{ MEDIA_URL }} tag for the image to be present (I'm not sure if this is a factor in the error I'm getting with sorl, or just a red-herring.
Now for some final tidbits of the original error (They are from the TemplateSyntaxError page being generated - last 5).
# /var/project/src/lib/sorl/thumbnail/base.py in get_thumbnail
36. thumbnail = ImageFile(name, default.storage)
37. cached = default.kvstore.get(thumbnail)
38. if cached:
39. return cached
40. if not thumbnail.exists():
41. # We have to check exists() because the Storage backend does not
42. # overwrite in some implementations.
43. source_image = default.engine.get_image(source) ...
44. # We might as well set the size since we have the image in memory
45. size = default.engine.get_image_size(source_image)
46. source.set_size(size)
47. self._create_thumbnail(source_image, geometry_string, options,
48. thumbnail)
49. # If the thumbnail exists we don't create it, the other option is
▼ Local vars Variable Value cached None file_ <EventImage: TestImage> geometry_string u'200x100' key 'format' name 'cache/24/69/246986cc89951f1d37235b8f0dec0a54.jpg' options {'colorspace': 'RGB', 'crop': False, 'format': 'JPEG', 'quality': 95, 'upscale': True} self <sorl.thumbnail.base.ThumbnailBackend object at 0x7f5b885f2c10> source <sorl.thumbnail.images.ImageFile object at 0x7f5b885c81d0> thumbnail <sorl.thumbnail.images.ImageFile object at 0x7f5b8867f510> value 'JPEG'
# /var/project/src/lib/sorl/thumbnail/engines/pil_engine.py in get_image
5. from PIL import Image, ImageDraw
6. except ImportError:
7. import Image, ImageDraw
8.
9.
10. class Engine(EngineBase):
11. def get_image(self, source):
12. buf = StringIO(source.read()) ...
13. return Image.open(buf)
14.
15. def get_image_size(self, image):
16. return image.size
17.
18. def dummy_image(self, width, height):
▼ Local vars Variable Value self <sorl.thumbnail.engines.pil_engine.Engine object at 0x7f5b886cf450> source <sorl.thumbnail.images.ImageFile object at 0x7f5b885c81d0>
# /home/caronc/Development/cityattention/src/lib/sorl/thumbnail/images.py in read
114. return self._size
115.
116. @property
117. def url(self):
118. return self.storage.url(self.name)
119.
120. def read(self):
121. return self.storage.open(self.name).read() ...
122.
123. def write(self, content):
124. if not isinstance(content, File):
125. content = ContentFile(content)
126. self._size = None
127. return self.storage.save(self.name, content)
▼ Local vars Variable Value self <sorl.thumbnail.images.ImageFile object at 0x7f5b885c81d0>
# /usr/lib/python2.6/site-packages/django/core/files/storage.py in open
25. # These shouldn't be overridden by subclasses unless absolutely necessary.
26.
27. def open(self, name, mode='rb', mixin=None):
28. """
29. Retrieves the specified file from storage, using the optional mixin
30. class to customize what features are available on the File returned.
31. """
32. file = self._open(name, mode) ...
33. if mixin:
34. # Add the mixin as a parent class of the File returned from storage.
35. file.__class__ = type(mixin.__name__, (mixin, file.__class__), {})
36. return file
37.
38. def save(self, name, content):
▼ Local vars Variable Value mixin None mode 'rb' name u'TestImage' self <django.core.files.storage.FileSystemStorage object at 0x7f5b8867f3d0>
# /usr/lib/python2.6/site-packages/django/core/files/storage.py in _open
130. location = settings.MEDIA_ROOT
131. if base_url is None:
132. base_url = settings.MEDIA_URL
133. self.location = os.path.abspath(location)
134. self.base_url = base_url
135.
136. def _open(self, name, mode='rb'):
137. return File(open(self.path(name), mode)) ...
138.
139. def _save(self, name, content):
140. full_path = self.path(name)
141.
142. directory = os.path.dirname(full_path)
143. if not os.path.exists(directory):
▼ Local vars Variable Value mode 'rb' name u'TestImage' self <django.core.files.storage.FileSystemStorage object at 0x7f5b8867f3d0>
I unsuccessfully Googled for this error; I'm hoping that my problem is just a quick one since everything is working except the template display.
The documentation was a bit weak in this field, but after importing the python debugger, I was able to find out where the problem was.
There are 2 potential solutions to this issue. The first one that fixed everything for me was to alter my template to read:
{% load thumbnail %}
...
{% thumbnail image.path "200x100" as im %}
<img src="{{ im.url }}" alt="{{ im.name }}"/>
{% endthumbnail %}
...
I'm guessing the issue still may be at my end; especially since this tool has been bulletproof for some time now. That said, those who are experiencing the same issue will need to add the .path argument to save themselves the grief I went through.
An alternative (not a very good one) option is to add this to your models.py and then reference the image directly again (as I did in my initial question).
def __unicode__(self):
return self.image.path
This of course is a nasty solution if the object containing the event your trying to display is not solely responsible for displaying images. Hence... the second option may only be ideal in 'some' situations. I'd stick with the first workaround.
This work-around is applicable to the 10.12.1 patch.
Also, to justify my initial question. I stated that static images were being created; as it turns out, this was incorrect. Although those images 'were' the correct thumbnails of the images I couldn't get to work on my page. They were being automatically generated from the DJango-Admin tool. Probably back when I was trying to upload different images (tackling the problem the wrong way). :)