在SORL缩略图和删除缩略图文件或在文件被覆盖时刷新缩略图方面存在问题。场景是,我有一个文件,每个条目总是相同的,但可以被覆盖。需要在上传新文件和覆盖旧文件时重新创建缩略图。
这是在model + form级别,所以我使用低级API来生成thumbs。
我尝试过使用:
from sorl.thumbnail import delete
delete(filename)但是如果没有成功,缩略图将永远不会被删除或覆盖。
我甚至尝试过:
from sorl.thumbnail.images import ImageFile
from sorl.thumbnail import default
image_file = ImageFile(filename)
default.kvstore.delete_thumbnails(image_file)同样没有成功。
请帮帮我!
更新:
我通过创建一个替代的ThumbnailBackend和一个新的_get_thumbnail_filename方法找到了一个变通方法。新方法使用文件的SHA-1散列来始终具有特定于当前文件的缩略图。
这是任何其他可能遇到类似情况的人的后端。
class HashThumbnailBackend(ThumbnailBackend):
def _get_thumbnail_filename(self, source, geometry_string, options):
"""
Computes the destination filename.
"""
import hashlib
# hash object
hash = hashlib.sha1()
# open file and read it in as chunks to save memory
f = source.storage.open(u'%s' % source, 'rb')
while True:
chunk = f.read(128)
if not chunk:
break
hash.update(hashlib.sha1(chunk).hexdigest())
# close file
f.close()
hash.update(geometry_string)
hash.update(serialize(options))
key = hash.hexdigest()
# make some subdirs
path = '%s/%s/%s' % (key[:2], key[2:4], key)
return '%s%s.%s' % (settings.THUMBNAIL_PREFIX, path,
self.extensions[options['format']])发布于 2011-02-23 08:08:50
这有点难以解释,所以我做了这张很棒的桌子。下面列出了第一列的命令,其他列使用X标记它是否删除。Original是原始文件,缩略图是原始文件的缩略图,KV表示键值存储引用。
| Command | Original | Thumbnails | KV Original | KV Thumbnails |
| #1 | X | X | X | X |
| #2 | | X | | X |
| #3 | | X | X | X |sorl.thumbnail.delete(filename)sorl.thumbnail.default.kvstore.delete_thumbnails(image_file)sorl.thumbnail.delete(filename, delete_file=False)据我所知,你真的想做第三件事。现在,你的问题是...有一种猜测是,相对于MEDIA_ROOT,filename并没有引用文件名(如果您使用的是另一个存储后端,情况也会类似)。但我认为我需要知道你在做什么以获得更好的图像,请注意ImageFields和FileFields不会覆盖,还请注意django在1.2.5中更改了删除行为,请参阅发行说明。
更新:任何阅读这篇文章的人都应该注意到,上面生成缩略图文件名的方式是效率极低的,如果你关心性能,请不要使用。
发布于 2012-11-16 07:21:33
我不完全确定这是否回答了你的问题,但我也遇到了同样的问题,这就是我的解决方案。
我有一个模型,上面有一个FileField,如下所示:
material = models.FileField(upload_to='materials')在处理上传的文件时,我使用get_thumbnail()来生成缩略图,将FileField作为参数传入,而不是在其后面传递python级别的文件。即:
thumb = get_thumbnail(modelinstance.material, '%dx%d' % (thumb_width, thumb_height))和你的问题一样,我还发现当一个文件具有相同的名称时,sorl只会从缓存中获取缩略图,而不是生成新的缩略图。令人恼火!
有效的方法是使用sorl的delete方法并传递FileField。我首先尝试在FileField对象后面传入python文件,这可能就是您正在尝试的?从这个开始:
sorl.thumbnail.delete(modelinstance.material.file)要这样做:
sorl.thumbnail.delete(modelinstance.material)似乎与sorl-缩略图的KV商店排成一列,并将适当地获得缓存的缩略图,以便可以从新文件创建新的缩略图。耶!
这对我很有帮助:http://sorl-thumbnail.readthedocs.org/en/latest/operation.html
此外,即使在运行./manage.py缩略图清理和./manage.py缩略图清除之后,我也无法让Django停止在同一位置查找旧缩略图。我不得不手动清除Django缓存(我使用的是memcached)。下面是你如何做到这一点:
import os
# Set the DJANGO_SETTINGS_MODULE environment variable.
os.environ['DJANGO_SETTINGS_MODULE'] = "yourproject.settings"
from django.core.cache import cache
# Flush!
cache._cache.flush_all()这是我的第一个SO答案。希望对某些人有帮助:)
发布于 2013-04-26 21:38:01
问题是,您不能将快捷方式delete(file)与File类一起使用,该文件类的与您通过get_thumbnail()或{% thumbnail ...%}模板标签生成缩略图时使用的不同。
原因是从文件对象构造的删除实例将获得不同的键(ImageFile.key),而ImageFile ()永远不能检索要删除的好的缩略图,因为键不匹配。
例如,如果您使用Python File对象,然后使用Django File对象,我不确定它是否会起作用,但在Django中,如果您使用FileField对象生成缩略图,并尝试使用File实例删除它(及其缩略图),它将不一定能正常工作。
所以,在你的模板中,不要这样做:
{% load thumbnail %}
{% thumbnail image "100" as im %}
<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}">
{% endthumbnail %}其中image是models.ImageField实例,但使用其file属性:
{% load thumbnail %}
{% thumbnail image.file "100" as im %}并在Python代码中将其删除(以下是Storage的示例,如果名称相同,则覆盖现有文件):
from django.core.files.storage import FileSystemStorage
from django.core.files import File
from sorl.thumbnail import delete
class OverwriteStorage(FileSystemStorage):
def _save(self, name, content):
if self.exists(name):
img = File(open(os.path.join(self.location, name), "w"))
delete(img)
return super(OverwriteStorage, self)._save(name, content)不确定是不是sorl中的bug,或者是否有充分的理由生成不同的键。
https://stackoverflow.com/questions/5072234
复制相似问题