2

我有一个照片模型,有两个图像字段。一个用于原始图像,另一个用于原始图像的调整大小的版本。Django频道调整图像大小

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的渠道来调整图像具有的470px宽度和使用SORL缩略图Django的imagekit或以任何其他方式自动高度?

+1

我不明白渠道如何做与调整图像大小。你能否详细说明你为什么要使用django-channels来完成这个任务,你是什么意思?另外,你是否已经死定在了sorl-thumbnail上?为同一图像的不同版本分开模型字段的模型看起来更像django-imagekit的胡同。 –

+0

@LudwikTrammer django-imagekit看起来很有前途。谢谢。我一定会试试这个。我选择django-channles的原因是因为我已经将它用于websocket的目的,并在他们的文档中说:“除此之外,还有很多非关键任务,应用程序可以轻松卸载,直到响应已发送 - 就像将内容保存到缓存或缩略图新上传的图像一样。“ – Karl

+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-缩略图将负责其余的(缩放在第一次请求时,处理缓存等)。它按需运行,即调整大小将在第一次访问时完成(当遇到模板标签时) - 这通常很好。您应该记住的唯一事情是,如果您的存储速度很慢,sorl-thumbnail将无法正常工作。如果您将媒体存储在本地驱动器上 - 没关系。如果您的存储后端是Amazon S3,请不要这样做。

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

如果您想要确保缩略图是用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一样缩略图,这实际上并不会创建数据库字段,如果您完全想要一个完全托管的独立映像文件,并拥有自己的数据库字段 - 似乎您最好的选择是使用裸枕头库在Photo.save中显式生成缩略图。)

然后,它只是简单明了:

<img src="{{ photo.image_470.url }}" 
    width="{{ photo.image_470.width }}" 
    height="{{ photo.image_470.height }}" 
    alt="..." /> 

一定要检查出的文档on caching这也解释了如何缓存的工作(和异步产生thumnails,你就想要这样)。