【问题标题】:How to make a thumbnail of a static image using sorl-thumbnail如何使用 sorl-thumbnail 制作静态图像的缩略图
【发布时间】:2014-09-22 12:54:36
【问题描述】:

我的 Django 项目中有一个带有头像字段的用户模型:

class User(AbstractBaseUser):

    avatar = models.ImageField(
        null=True,
        blank=True,
        upload_to='user/avatar/',
    )

头像不是必需的,所以如果用户尚未上传头像,我想使用默认图像。另一方面,我不想使用default 参数以便将来能够为所有用户更改默认头像:

class User(AbstractBaseUser):

    avatar = models.ImageField(
        null=True,
        blank=True,
        default='defaults/no-avatar.png',
        upload_to='user/avatar/',
    )

所以我最终编写了一个get_avatar 方法,如果头像存在或默认静态图像的路径返回图像:

@property
def get_avatar(self):
    if self.avatar:
        return self.avatar
    return '{0}defaults/no-avatar.png'.format(settings.STATIC_URL)

但在这种情况下,sorl-thumbnail 不会为默认图像生成缩略图

{% thumbnail user.get_avatar "46x46" crop="center" as im %}
    <img title="{{ user }}" src="{{ im.url }}" class="img-circle" />
{% endthumbnail %}

并返回以下错误:

ERROR 2014-09-22 12:49:48,020 thumbnail :: Thumbnail tag failed:
Traceback (most recent call last):
  File "/Users/vera/.virtualenvs/my_app/lib/python2.7/site-packages/sorl/thumbnail/templatetags/thumbnail.py", line 45, in render
    return self._render(context)
  File "/Users/vera/.virtualenvs/my_app/lib/python2.7/site-packages/sorl/thumbnail/templatetags/thumbnail.py", line 97, in _render
    file_, geometry, **options
  File "/Users/vera/.virtualenvs/my_app/lib/python2.7/site-packages/sorl/thumbnail/base.py", line 56, in get_thumbnail
    source_image = default.engine.get_image(source)
  File "/Users/vera/.virtualenvs/my_app/lib/python2.7/site-packages/sorl/thumbnail/engines/pil_engine.py", line 12, in get_image
    buf = StringIO(source.read())
  File "/Users/vera/.virtualenvs/my_app/lib/python2.7/site-packages/sorl/thumbnail/images.py", line 121, in read
    return self.storage.open(self.name).read()
  File "/Users/vera/.virtualenvs/my_app/lib/python2.7/site-packages/django/core/files/storage.py", line 33, in open
    return self._open(name, mode)
  File "/Users/vera/.virtualenvs/my_app/lib/python2.7/site-packages/django/core/files/storage.py", line 159, in _open
    return File(open(self.path(name), mode))
  File "/Users/vera/.virtualenvs/my_app/lib/python2.7/site-packages/django/core/files/storage.py", line 260, in path
    raise SuspiciousFileOperation("Attempted access to '%s' denied." % name)

我尝试重写该方法以返回图像:

from django.core.files.images import ImageFile

@property
def get_avatar(self):
    if self.avatar:
        return self.avatar
    return ImageFile(open(os.path.join(settings.STATIC_ROOT, 'defaults/no-avatar.png'), 'r'))

但我遇到了类似的错误:

ERROR 2014-09-22 12:52:18,448 thumbnail :: Thumbnail tag failed:
Traceback (most recent call last):
  File "/Users/vera/.virtualenvs/my_app/lib/python2.7/site-packages/sorl/thumbnail/templatetags/thumbnail.py", line 45, in render
    return self._render(context)
  File "/Users/vera/.virtualenvs/my_app/lib/python2.7/site-packages/sorl/thumbnail/templatetags/thumbnail.py", line 97, in _render
    file_, geometry, **options
  File "/Users/vera/.virtualenvs/my_app/lib/python2.7/site-packages/sorl/thumbnail/base.py", line 56, in get_thumbnail
    source_image = default.engine.get_image(source)
  File "/Users/vera/.virtualenvs/my_app/lib/python2.7/site-packages/sorl/thumbnail/engines/pil_engine.py", line 12, in get_image
    buf = StringIO(source.read())
  File "/Users/vera/.virtualenvs/my_app/lib/python2.7/site-packages/sorl/thumbnail/images.py", line 121, in read
    return self.storage.open(self.name).read()
  File "/Users/vera/.virtualenvs/my_app/lib/python2.7/site-packages/django/core/files/storage.py", line 33, in open
    return self._open(name, mode)
  File "/Users/vera/.virtualenvs/my_app/lib/python2.7/site-packages/django/core/files/storage.py", line 159, in _open
    return File(open(self.path(name), mode))
  File "/Users/vera/.virtualenvs/my_app/lib/python2.7/site-packages/django/core/files/storage.py", line 260, in path
    raise SuspiciousFileOperation("Attempted access to '%s' denied." % name)
SuspiciousFileOperation: Attempted access to '/Users/vera/workspace/my-website/static/defaults/no-avatar.png' denied.

【问题讨论】:

    标签: django sorl-thumbnail


    【解决方案1】:

    sorl-thumbnail 使用了storage functionality。 Django 将有关如何以及在何处存储文件的决定委托给file storage system。这是真正理解文件系统、打开和读取文件等内容的对象。Django 附带一个 django.core.files.storage.FileSystemStorage 类,它实现了基本的本地文件系统文件存储。默认情况下,Django 使用 MEDIA_ROOT 和 MEDIA_URL 设置在本地存储文件。

    因此,在您的情况下,django 尝试在 MEDIA_ROOT 下查找图像,但您已将图像保存在 STATIC_ROOT 下。

    如何解决这个问题

    作为修补程序,您可以尝试在 MEDIA_ROOT 下移动图像,并在 get_avatar 方法中更改路径。 或者您可以尝试编写自定义存储,这将与两个文件夹一起使用。 Example custom storage.

    【讨论】:

      猜你喜欢
      • 2015-06-14
      • 2012-09-18
      • 2011-07-01
      • 2012-03-06
      • 2012-06-12
      • 2014-01-22
      • 2016-05-10
      • 2010-11-27
      • 2011-02-13
      相关资源
      最近更新 更多