如何在django中为sorl-thumbnail设计清理任务?

时间:2013-12-09 08:38:38

标签: python django celery django-celery sorl-thumbnail

我正在使用sorl-thumbnail,它提供给定图像的缓存缩略图。 我想在原始图像更改或删除时删除生成的拇指。 我知道sorl-thumbnail为这种情况提供了一种删除方法,但是..

  • 不会通过django-admin
  • 触发
  • 可能是竞争条件的不良原因
  • 使用像redis这样的kv商店时 - 所有数据(文件连接)可能都会消失(例如重启)

更合适的是sorl清理管理命令。此命令将删除具有损坏原始链接的kv条目和关联的物理拇指。但是如果我的kv存储不完整怎么办?我不希望有死文件。

我想到了芹菜任务,它将触发清理命令并另外检查所有缓存的文件,但不知道如何设计。

检测和清理混乱的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

您可以向模型添加clear_thumbnails()方法。在clear_thumbnails()中,您使用sorl-thumbnail中的delete function删除现有缩略图。如果下次渲染视图时呈现{% thumbnail %}模板标记,则会创建新的缩略图。

现在添加一个在调用与缩略图相关的模型的pre_save signal时运行的函数。在这个函数中,你可以简单地调用clear_thumbnails()

使用此方法,当您在Django admin中更改模型时,也会删除缩略图。 (你也可以捕捉pre_delete信号)

这样的事情:

## models.py ##
from django.db import models
from sorl.thumbnail import delete as delete_thumbnails

class Route(models.Model):
    ...
    def clear_thumbnails(self):
        delete_thumbnails(self.image)

## receivers.py ##
from django.db.models.signals import pre_save

@receiver(pre_save, sender=YourModel)
def receive_yourmodel_pre_save(sender, **kwargs):
    sender.clear_thumbnails()

现在您有一个模型可以在模型更改时删除缩略图。 (如果图像字段发生了变化,你应该在pre_save或post_save信号中添加一个检查,如果发生这种情况,只删除缩略图)

如果你有很多缩略图,那么sorl-thumbnails的管理命令就没用了。我在sorl-thumbnails键值存储中有几百万个条目,管理命令永远不会完成。

我最终编写了自己的小清理脚本,它比sorl-thumbnails提供的更好,因为它没有使用如此多的内存并且还显示了进度。像这样:

function clean_thumbnails(self):
    max_id = MyModel.objects.all().order_by('-pk')[0].pk

    for id in xrange(max_id, 0, -1):
        try:
            my_obj = MyModel.objects.get(pk=id)
            my_obj.clear_thumbnails()
            print "processed object with id %s" % id
        except MyModel.DoesNotExist:
            pass

我将此清理脚本设置为RunScript as defined the Django extensions。查看Django扩展和RunScript部分。这非常方便。

希望这有帮助。