Использование статических изображений с sorl-thumbnail - PullRequest
5 голосов
/ 20 сентября 2011

Я пытаюсь предоставить миниатюру файла, который находится в моей папке STATIC_ROOT.На самом деле не имеет значения, попадет ли он в MEDIA_URL / cache, но sorl-thumbnail не будет загружать изображение из статической папки.

текущий код:

{% thumbnail "images/store/no_image.png" "125x125" as thumb %}

взлом, который работает

{% thumbnail "http://localhost/my_project/static/images/store/no_image.png" "125x125" as thumb %}

Мне не нравится хак, потому что A) Он не сухой (мой проект фактически обслуживается из подкаталога / B) Он использует http, чтобы получить файл, который всего 3каталоги подальше, кажутся бессмысленно неэффективными

Ответы [ 5 ]

3 голосов
/ 23 июня 2012

Шаблон фильтра работает.Но я не уверен, происходит ли каждый раз чтение из памяти.Если это так, это необоснованно ...

from django.template import Library
from django.core.files.images import ImageFile
from django.core.files.storage import get_storage_class
register = Library()

@register.filter
def static_image(path):
    """
    {% thumbnail "/img/default_avatar.png"|static_image "50x50" as img %}
        <img src="{{ MEDIA_URL }}{{img}}"/>
    {% endthumbnail %}
    """
    storage_class = get_storage_class(settings.STATICFILES_STORAGE)
    storage = storage_class()
    image = ImageFile(storage.open(path))
    image.storage = storage
    return image
2 голосов
/ 13 апреля 2012

Я работал над этим, передавая файл в контекст шаблона из моего представления.

Вот пример функции util, которую я вызвал из своих представлений:

def get_placeholder_image():
    from django.core.files.images import ImageFile
    from django.core.files.storage import get_storage_class
    storage_class = get_storage_class(settings.STATICFILES_STORAGE)
    storage = storage_class()
    placeholder = storage.open(settings.PLACEHOLDER_IMAGE_PATH)
    image = ImageFile(placeholder)
    image.storage = storage
    return image

Возможно, вы могли бысделать что-то похожее на пользовательский тег шаблона.

2 голосов
/ 20 сентября 2011

Предполагая, что вы используете Django 1.3, вы должны взглянуть на документы о Управление статическими файлами

Если вы все настроите правильно, вы можете включить ваши изображения следующим образом:

<img src="{{ STATIC_URL }}images/store/no_image.png" />
0 голосов
/ 01 февраля 2013

Значение по умолчанию для настройки sorl THUMBNAIL_STORAGE - это те же настройки. DEFAULT_FILE_STORAGE.

Вы должны создать хранилище, которое использует STATIC_ROOT, например, вы можете использовать 'django.core.files.storage.FileSystemStorage' и создать экземпляр с location = settings.STATIC_ROOT и base_url = settings.STATIC_URL

Только THUMBNAIL_STORAGE, установленный в настройках для MyCustomFileStorage, не работал. Так что мне пришлось сделать с DEFAULT_FILE_STORAGE, и это сработало.

Определить в settings.py:

DEFAULT_FILE_STORAGE = 'utils.storage.StaticFilesStorage'

Utils / storage.py:

import os
from datetime import datetime

from django.conf import settings
from django.core.files.storage import FileSystemStorage
from django.core.exceptions import ImproperlyConfigured


def check_settings():
    """
    Checks if the MEDIA_(ROOT|URL) and STATIC_(ROOT|URL)
    settings have the same value.
    """
    if settings.MEDIA_URL == settings.STATIC_URL:
        raise ImproperlyConfigured("The MEDIA_URL and STATIC_URL "
                                   "settings must have different values")
    if (settings.MEDIA_ROOT == settings.STATIC_ROOT):
        raise ImproperlyConfigured("The MEDIA_ROOT and STATIC_ROOT "
                                   "settings must have different values")




class TimeAwareFileSystemStorage(FileSystemStorage):
    def accessed_time(self, name):
        return datetime.fromtimestamp(os.path.getatime(self.path(name)))

    def created_time(self, name):
        return datetime.fromtimestamp(os.path.getctime(self.path(name)))

    def modified_time(self, name):
        return datetime.fromtimestamp(os.path.getmtime(self.path(name)))



class StaticFilesStorage(TimeAwareFileSystemStorage):
    """
    Standard file system storage for static files.

    The defaults for ``location`` and ``base_url`` are
    ``STATIC_ROOT`` and ``STATIC_URL``.
    """
    def __init__(self, location=None, base_url=None, *args, **kwargs):
        if location is None:
            location = settings.STATIC_ROOT
        if base_url is None:
            base_url = settings.STATIC_URL
        if not location:
            raise ImproperlyConfigured("You're using the staticfiles app "
                                       "without having set the STATIC_ROOT setting. Set it to "
                                       "the absolute path of the directory that holds static files.")
            # check for None since we might use a root URL (``/``)
        if base_url is None:
            raise ImproperlyConfigured("You're using the staticfiles app "
                                       "without having set the STATIC_URL setting. Set it to "
                                       "URL that handles the files served from STATIC_ROOT.")
        if settings.DEBUG:
            check_settings()
        super(StaticFilesStorage, self).__init__(location, base_url, *args, **kwargs)

Справка:

https://github.com/mneuhaus/heinzel/blob/master/staticfiles/storage.py

https://docs.djangoproject.com/en/dev/ref/settings/#default-file-storage

0 голосов
/ 17 октября 2012

В итоге я перехватил тот факт, что он может получить URL-адрес, и написал свой собственный тег, который переопределяет метод _render на ThumbnailNode:

from django.template import Library

from django.contrib.sites.models import Site
from django.contrib.sites.models import get_current_site


from sorl.thumbnail.templatetags.thumbnail import ThumbnailNode as SorlNode
from sorl.thumbnail.conf import settings
from sorl.thumbnail.images import DummyImageFile
from sorl.thumbnail import default

register = Library()


class ThumbnailNode(SorlNode):
    """allows to add site url prefix"""

    def _render(self, context):
        file_ = self.file_.resolve(context)
        if isinstance(file_, basestring):
            site = get_current_site(context['request'])
            file_ = "http://" + site.domain + file_

        geometry = self.geometry.resolve(context)
        options = {}
        for key, expr in self.options:
            noresolve = {u'True': True, u'False': False, u'None': None}
            value = noresolve.get(unicode(expr), expr.resolve(context))
            if key == 'options':
                options.update(value)
            else:
                options[key] = value
        if settings.THUMBNAIL_DUMMY:
            thumbnail = DummyImageFile(geometry)
        elif file_:
            thumbnail = default.backend.get_thumbnail(
                file_, geometry, **options
                )
        else:
            return self.nodelist_empty.render(context)
        context.push()
        context[self.as_var] = thumbnail
        output = self.nodelist_file.render(context)
        context.pop()
        return output


@register.tag
def thumbnail(parser, token):
    return ThumbnailNode(parser, token)

Тогда из шаблона:

{% with path=STATIC_URL|add:"/path/to/static/image.png" %}
{% thumbnail path "50x50" as thumb %}
<img src="{{ thumb.url }}" />
...

Не самое удачное решение ...: - /

...