cloudinaryを利用する
herokuにアプリをアップロードして、modelsにImageFieldを登録して、画像を投稿すると、画像が表示されなかったので調べてみると、herokuは画像や動画などのアップロードに対応していないみたいです。
HTMLの中に埋め込んだ画像は表示されるので、ソースコードの中のstaticfilesはちゃんと保存してくれているみたいです
調べると、ファイルをアップロードできるサーバーとして、AWS S3とcloudinaryが選択肢としてありましたが、AWSは1年経つと有料になってしまうみたいで、趣味レベルでしかない私には気が引けたので、フリーパックがあったcloudinaryにしました。cloudinaryは、herokuのアドオンにも入っているので、導入も簡単かな?と思いました。
主に公式ドキュメント(上)と、個人の方の書き込みを(下)を参考にしました。
参照:https://cloudinary.com/documentation/django_integration
https://pypi.org/project/django-cloudinary-storage/0.1.2/
cloudinaryに登録する
herokuのホームぺージのアドオンからcloudinaryを探し、中を見ると、フリープランのインストールボタンがあるので押します。
すると、cloudinaryを利用するアプリを聞かれるので入力すると、cloudinaryのページに飛びます。はじめに使用する言語などを聞かれるので、それらに答えるとダッシュボードが見れるようになります。
cloudinaryのインストール
コンソール上で、仮想環境に入り、cloudinaryのパッケージのインストールを行います。
$ pip install django-cloudinary-storage
画像ファイルを扱う場合は、Pillowが必要なので、入っていない場合はPillowもここでインストールします。
$ pip install Pillow
忘れずに、requirements.txtに書き込みます
pip freeze > requirements.txt
settings.pyへの書き込み
Djangoのsettings.pyのINSTALLED_APPSに"cloudinary"と"cloudinary_storage"を書き込んでください。
この時、cloudinary_storageを書く位置で私ははまりました。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'homepage',
'cloudinary',
'cloudinary_storage',
]
"cloudinary"も"cloudinary_storage"も、最後に書くようにして下さい。正確に言うと、"django.contrib.staticfiles"より前には書かないようにしてください。
参照したページでは、"django.contrib.staticfiles"より前に"cloudinary_storage"を書くようにという指示がありましたが、その順に書くと、herokuにデプロイした時にstaticファイルが読み込まれなくなります。
私は英語に疎いので、"django.contrib.staticfiles"より前に"cloudinary_storage"を書くなんらかの理由があってそれを見逃しているのかもしれませんが、現状では、私が書いた順でstaticファイルは正常に読み込まれていて、"cloudinary"へのファイルのアップロード、ファイルの呼び出しも正常にできています。
今後、何かトラブルが起きたら、加筆・修正を行いたいと思います。
さらに、cloudinaryのアカウント情報を読み込ませます。settings.pyの最終行に
CLOUDINARY_STORAGE = {
'CLOUD_NAME': 'your_cloud_name',
'API_KEY': 'your_api_key',
'API_SECRET': 'your_api_secret'
}
と書きます。それぞれの中身は、cloudinaryのダッシュボードを見ると書いてあるのでそれをコピペしてください。
importに関して
公式ドキュメントでは、
import cloudinary
import cloudinary.uploader
import cloudinary.api
と記述するようにという指示がありますが、私のようにmodelsの投稿用に画像を保存するだけだったら、この記述は必要ないみたいです。settings.pyの最後に
DEFAULT_FILE_STORAGE = 'cloudinary_storage.storage.MediaCloudinaryStorage'
と書くだけで、models.pyはいじらなくても、ImageFieldとcloudinaryが勝手に紐づきます。この時点で、adminで投稿した画像はページ上で正常に表示されるようになりました。
<img src="{{ test_model_instance.image.url }}" alt="{{ test_model_instance.image.name }}">
と書けば、画像をHTML上に直接引っ張ってこれるみたいです。
所感
なんとか、cloudinaryをmodelsと紐づけることができました。さすがに、djangoにcloudinaryという日本ではマイナーな組み合わせだったので、英語ページしかなかったのが苦しかったです。
正直、私もぜいぜい言いながら作ったので、無駄な部分とか、逆にこの記事に書ききれていない部分があるかもしれません。うまくいかない方がいたら教えてください。可能な範囲でお答えできればと思います。