我有一个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 或以任何其他方式?
答案 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,其中解释了缓存的工作原理(以及异步生成梯形图,您是否希望这样做)。