jazzband / sorl-thumbnail

Thumbnails for Django
https://sorl-thumbnail.readthedocs.io
BSD 3-Clause "New" or "Revised" License
1.74k stars 496 forks source link

Cannot get sorl-thumbnail to work with MEDIA_ROOT set #397

Open qcaron opened 9 years ago

qcaron commented 9 years ago

Hi there !

If I do not set MEDIA_ROOT and MEDIA_URL in my settings, the static/cache directory gets filled with images. But when settings MEDIA_ROOT and MEDIA_URL then it does not work anymore.

I am using Django 1.8.3 and Python 2.7.6 with pipeline 1.5.3. I am testing locally so please note that DEBUG=True, TEMPLATE_DEBUG = DEBUG and THUMBNAIL_DEBUG = DEBUG.

I have referenced this in a stackoverflow question but I fear I will not get an answer there. So here it is:

Here are my settings:

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

DEBUG = True
TEMPLATE_DEBUG = DEBUG

INSTALLED_APPS = (
    'django.contrib.sites',
    'grappelli',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'djangobower',
    'pipeline',
    'sorl.thumbnail',
    'django_countries',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    # Local apps
    ...

STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
STATICFILES_STORAGE = 'pipeline.storage.PipelineStorage'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

THUMBNAIL_DEBUG = DEBUG
THUMBNAIL_PREFIX = 'cache/'

STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    'pipeline.finders.PipelineFinder',
)

# TODO : use redis in prod
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
        'LOCATION': 'cache',
    }
}

My home.html file contains this:

{% extends 'base.html' %}

{% load static i18n thumbnail %}

{% static 'main/img/business_man_in_the_mirror.jpg' as business_man_in_the_mirror %}
{{ business_man_in_the_mirror }}
{% thumbnail business_man_in_the_mirror|slice:"1:" "x300" as im %}
    {{ im.url }}
    <img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}"
         alt="{% trans "Homme d'affaire se regardant dans le miroir" %}"
         class="center-block img-responsive">
{% endthumbnail %}

{{ business_man_in_the_mirror }} prints "/static/main/img/business_man_in_the_mirror.jpg". {{ im.url }} prints "/media/cache/d0/38/d038a3e64b2c7d070088e368ee881027.jpg"

So far so good. But the cache folder in MEDIA_ROOT never gets created. The MEDIA_ROOT even has 777 rights. I do not see any error from ./manage.py runserver -v 3. So the image is missing in my web page.

The runserver log shows the following:

[10/Aug/2015 18:47:47]"GET /media/cache/d0/38/d038a3e64b2c7d070088e368ee881027.jpg HTTP/1.1" 404 2870

http://localhost:8000/static/main/img/business_man_in_the_mirror.jpg does show me the image.

I tried all thumbnail Management Commands but it had no effect. I also tried to delete the tumbnail_kvstore table and the cache table in DB, changed nothing. I have 5 rows in cache table but nothing in thumbnail_kvstore table.

Thanks for your help!!

caioariede commented 9 years ago

Didn't you skip this step?

https://docs.djangoproject.com/en/1.8/howto/static-files/#serving-files-uploaded-by-a-user-during-development

qcaron commented 9 years ago

No I did not skip it, it's in my ROOT_URLCONF.

qcaron commented 9 years ago

As my images are NOT located in the MEDIA_ROOT but in STATIC_ROOT, can thumbnail create thumbnails in MEDIA_ROOT/cache for my static mages ?

Because it just looks like thumbnail tries to find my images in MEDIA_ROOT/static/main/img and does not find them which is normal. But then how to serve thumbnails for static images ?

qcaron commented 9 years ago

OK so I copied my static/main/img in my MEDIA_ROOT and it worked. It means that everything that can be served from sorl-thumbnails must be located in the MEDIA_ROOT.

My conclusion: only user uploded files can be thumbnailed.

So should I cache images in my template and save resized images before serving them?

relekang commented 9 years ago

OK so I copied my static/main/img in my MEDIA_ROOT and it worked. It means that everything that can be served from sorl-thumbnails must be located in the MEDIA_ROOT.

I think this because of how Django's file storage backend. If things are outside the MEDIA_ROOT you should see a suspicious file operation error raised by Django. I guess it is swallowed in a "too general" except-clause somewhere?

A way to work around this for static files is to prefix the static paths you pass to sorl-thumbnails with the domain name (e.g. http://example.com/static/img.png).

qcaron commented 9 years ago

Well that made me crazy at some point: I did not see any exception or warning until I gave a path outside MEDIA_ROOT:

SuspiciousFileOperation at /
The joined path (/Users/quentin/Python/projects/static/main/img/business_man_in_the_mirror.jpg) 
is located outside of the base path component (/Users/quentin/Python/projects/djangoproject).

So sorl-thumbnail is ok with my image' abstract static file because it's located under my django project path. But then it does not copy or find the static file. It really looks like a bug. I mean, if all images must be in MEDIA_ROOT, then not finding an abstract path should raise an error because it seems sorl-thumbnail is looking in media/static/main/img/business_man_in_the_mirror.jpg and fails silently.

qcaron commented 9 years ago

@relekang I tried your workaround and it worked. However, it created a cache folder in my project root directory. Since media/cache is created for media then how could agree with a cache folder is served for static files? If it is a bit odd with DEBUG=True and STATIC_URL='/static/' but it is an acceptable solution for a production environment isn't it?

relekang commented 9 years ago

However, it created a cache folder in my project root directory.

That is a bit strange, I would expect it to use the regular cache folder in media.

qcaron commented 9 years ago

Yes indeed. I finally decided not to go with sorl-thumbnail for my static images. Should I open a feature request for this?

chiragsoni2401 commented 5 years ago

Hi there, I am using MEDIA_ROOT directory but for me, images are not showing. I am using ImageField that comes from pillow as stated in a sorl-thumbnail official documention that we can use it.