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,你就想要這樣)。