Django通道调整图像大小

时间:2016-08-24 19:20:03

标签: django django-models sorl-thumbnail django-imagekit django-channels

我有一个Photo模型,有两个图像区域。一个用于原始图像,另一个用于原始图像的调整大小版本。

class Photo(models.Model):
    user = models.ForeignKey(User)
    image_original = models.ImageField(
        upload_to=get_upload_file_name,
        width_field="image_original_width",
        height_field="image_original_height",
        blank=True
    )
    image_original_width = models.IntegerField(default=0)
    image_original_height = models.IntegerField(default=0)
    image_470 = models.ImageField(
        upload_to=get_upload_file_name,
        width_field="image_470_width",
        height_field="image_470_height",
        blank=True
    )
    image_470_width = models.IntegerField(default=0)
    image_470_height = models.IntegerField(default=0)

我选择django-channles的原因是因为我已经将它用于websocket目的,并且在文档中他们说" ...除此之外,还有很多非关键的应用程序可以轻松卸载的任务,直到发送响应为止 - 例如将内容保存到缓存中或缩略图上新上传的图像。"

我如何使用 django-channels 使用 sorl-thumbnail django-imagekit 或以任何其他方式?

1 个答案:

答案 0 :(得分:0)

如果您想使用sorl-thumbnail,那么您不需要在模型代码中执行任何操作。只要有这样的课程:

class Photo(models.Model):
    user = models.ForeignKey(User)
    image = models.ImageField(
        upload_to=get_upload_file_name,
        width_field="width",
        height_field="height",
        blank=True
    )
    width = models.IntegerField(default=0)
    height = models.IntegerField(default=0)

每当您需要470px图像时,请在模板中执行以下操作:

{% load thumbnail %}
...

{# Specifying width only here. #}
{# If you want a height constraint as well use e.g. "470x1000". #}
{% thumbnail photo.image "470" as im %}
    <img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}">
{% endthumbnail %}

就是这样 - sorl-thumbnail会处理剩下的事情(扩展第一个请求,处理缓存等)。它按需运行,即调整大小将在第一次访问时(遇到模板标签时) - 这通常很好。您应该记住的唯一事情是,如果您的存储空间缓慢,则sorl-thumbnail将无法正常工作。如果您将媒体存储在本地驱动器上 - 那很好。如果您的存储后端是,例如,亚马逊S3 - 不要这样做。

方便的部分是你需要其他缩略图大小,你只需要在你的模板代码中告诉你需要它们的sorl-thumnail。无需更改模型。

如果您想确保使用sorl-thumbnail预先生成缩略图,您可以明确地调用get_thumbnail或使用,例如一个Celery任务,为您运行get_thumbnail(忽略结果),例如

@app.task
def ensure_thumbnail(photo_pk, size="470"):
    photo = Photo.objects.get(pk=photo_pk)
    get_thumbnail(photo.image, size)

每当您看到新的上传内容时,请致电ensure_thumbnail.delay(photo.pk)

请务必查看the examples以获取更多信息。

如果您认为这种方法不是您想要的方式,或者您的存储速度较慢,那么请使用django-imagekit。我对它并不熟悉(我自己没有在生产中使用过),但根据文档看起来像这样:

您的模型看起来像:

from imagekit.models import ImageSpecField
from imagekit.processors import ResizeToFit
...

class Photo(models.Model):
    user = models.ForeignKey(User)
    image_original = models.ImageField(
        upload_to=get_upload_file_name,
        width_field="image_original_width",
        height_field="image_original_height",
        blank=True
    )
    image_original_width = models.IntegerField(default=0)
    image_original_height = models.IntegerField(default=0)
    # I haven't found a way to not specify the height.
    image_470 = ImageSpecField(source="image_original",
                               processors=[ResizeToFit(470, 1000)],
                               format="JPEG")

(与sorl-thumbnail一样,这实际上不会创建数据库字段。如果您绝对需要一个完全托管的独立映像文件,并且拥有自己的数据库字段 - 似乎您最好的选择是在{{1}中显式生成缩略图使用裸枕头库。)

然后它简单明了:

Photo.save

请务必查看文档on caching,其中解释了缓存的工作原理(以及异步生成梯形图,您是否希望这样做)。