はじめに
Djangoには便利なライブラリがたくさんあります。 ImageKitも、その1つで画像を自動的にリサイズしたり編集してくれます。Djangoのmodels.pyに下記のように書いてあげるだけの簡単操作です。
class Data(models.Model):
image = models.ImageField(upload_to='/path/',
default="path/to/image/.jpg")
middle = ImageSpecField(source='image',
processors=[ResizeToFill(1600, 1200)],
format="JPEG",
options={'quality': 100}
)
small = ImageSpecField(source='image',
processors=[ResizeToFill(640, 480)],
format="JPEG",
options={'quality': 100}
)
余談ですがdefautl画像の設定をしておくのが吉です。htmlでレンダリングした際に画像が無ければエラーが出ることがあります。自分の環境ではローカルでは発生しなかったのですが実際にデプロイした際にエラーが出たのでdefault画像を設定しました。
HTMLファイルのテンプレートには
{% for image in images %}
<img src="{{ image.small.url }}" >
{% endfor %}
と記載すると画像が表示されます。
Viewはこんな風にテンプレートに渡してあげます。流れを示しているだけなので適宜置き換えたり処理を追加してください。
from .models import Data
def view(request):
data = Data.objects.all()
return render(request, 'index.html',
{'images' : data
})
これだけの処理でリサイズされた画像が簡単に表示できちゃいます。
HTMLタグにリンクタグつけるだけでサムネイル画像にもなりますし、使い勝手はいいです。
問題発生
Webサービスを作っている際に、そろそろデプロイしようと思ってHerokuをプラットフォームとして選択しました。 Herokuを使うのは初めてでしたが、簡単に公開できて感動しました! しかし画像をアップロードしてもちょっとすると画像が消えている...調べてみるとどうやらHerokuは画像やらのストレージとしては機能しないらしいので画像だけはAmazon S3などの他のファイルサーバから配信するのが普通だそうで。
配信方法についてはこちらなどを参考にさせて頂きました。
ここまではすんなり行きましたが
I/O operation on closed file
とエラーが発生。
どうやらAWSを使う際にライブラリのboto3を用いているのですが、それとの相性が悪いらしい。
この問題はimagekitのissueでも議論されており
class CustomS3Boto3Storage(S3Boto3Storage)
カスタムクラスを作成することで回避することが可能となっています。
全てソースコード載せるのは憚られたので上のissueを見てください。