DjangoからAmazonS3にファイルを登録する
前回の記事でDjangoにモデルに画像を登録することができるようになりました。
ただ、実際に運用する際には、このままDjangoの中に画像を保存しておくのはパフォーマンス上あまりよくありません。
そこで今回は、モデルに登録した画像を、Amazon S3にアップロードできるようにする方法を紹介します。
Amazon S3とは?
Amazon S3はクラウドのストレージサービスです。簡単に説明するとDropboxのようにファイルを保管しておくことができるサービスです。詳しくはAWSのサイトをみてください。
AWSを使っているのなら、ファイルの保管には、基本的にAmazon S3を使うことになるかと思います。たくさんのファイルを保管してもそれなりに安いですし、耐久性も99.999999999%(!!!)と非常に高いです。
Amazon S3のIAMユーザーを準備する
AWS側の設定としてまず必要なのは、Amazon S3を利用できるIAMユーザーを作成することです。
まずAWSマネジメントコンソールに、ルートユーザーとしてログインします。それからサービス一覧の中からIAMを選択します。
左側のメニューから[ユーザー]を選択して、ユーザー一覧画面に移ります。
続いて、[ユーザーを追加]ボタンを押して、ユーザー作成を始めます。
ユーザ名を適当に設定します。
[AWSアクセスの種類を選択]では、今回[プログラムによるアクセス]と[AWSマネジメントコンソールへのアクセス]を両方使うので、両方にチェックを入れておきます。
次に進んでポリシーの選択です。[既存のポリシーを直接アタッチ]タブを選択して検索バーにS3と入力します。
[AmazonS3FullAccess]というポリシーがあるのでそれにチェックを入れて次に進みます。
タグは必要なら作成してください。
最後に、設定内容に問題ないか確認して完了です。
このページに表示されるアクセスキーID、シークレットアクセスキー、パスワードは重要なので、厳重に管理してください。これらの情報が含まれる.csvファイルをダウンロードしておくのが良いでしょう。
これでIAMユーザーの作成は完了です。
Amazon S3のバケットを準備する
早速、いま作成したIAMユーザーで、AWSマネジメントコンソールにログインしていきましょう。.csvファイルをダウンロードしたなら、その中のConsole login linkのアドレスにアクセスして、ログインしてください。
そして今度は、サービスの一覧からAmazon S3を探してクリックします。
Amazon S3にアクセスしたら、オレンジ色の[バケットを作成]ボタンからバケットの作成を始めます。
バケットとは、Amazon S3でのフォルダのようなものです。アプリケーションごとにフォルダを作って、管理しやすいようにわけておく、ぐらいの認識で大丈夫です。
バケット名は他のユーザーと被らない一意の名前にしなくてはなりません。僕の場合は、アプリ名に自分の名前を足したバケット名にしておきます。
その他の設定はとりあえずデフォルトのままで大丈夫です。
正常に作成されれば、Amazon S3のバケット一覧に表示されるようになります。
これでAmazon S3側の準備は完了です。
あとは、DjangoからAmazon S3に接続できるようにしていきましょう。
DjangoからAmazon S3に接続するパッケージ
まずは、必要なパッケージとしてdjango-storagesをインストールします。
pip install django-storages
django-storagesでAmazon S3に接続するにはboto3パッケージも必要ですので、それもインストールします。
pip install boto3
これで必要なパッケージは揃いました。
Djangoのsettings.pyの変更
今回は、練習としてsettings.pyを直接編集しますが、本来は開発用のsettings.pyと本番環境用のsettings.pyを作成しておいた方が良いです。どうやってやったらいいかに関しては、別の記事で書きます。
ここから、django-storagesで使う設定を追加していきます。以下の3行を追加してください。
# settings.py
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
AWS_STORAGE_BUCKET_NAME = 'skilla-daikinishimatsu'
AWS_S3_REGION_NAME = 'ap-northeast-1'
DEFAULT_FILE_STORAGEはそのままで問題ありませんが、AWS_STORAGE_BUCKET_NAMEには先ほどあなたが作成した、S3バケットの名前を入力してください。
AWS_S3_REGION_NAMEも他のリージョンでバケットを作成した場合は、変更が必要です。
続いて、AWSにアクセスするために使うキーを設定します。キーは直接コードに書くのはあまり良くないので、環境変数に値を入れるようにします。
環境変数とは、OS内で共有されている変数のようなものです。重要な情報は、直接コードに書かずに環境変数に入れておくことが多いです。
# settings.py
AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
Djangoのsettings.pyにこれらを追加したらAWS_ACCESS_KEY_IDとAWS_SECRET_ACCESS_KEYの環境変数を作成しておきます。
bashの場合は、以下のコマンドを入力すれば環境変数を作成できます。
export AWS_ACCESS_KEY_ID="あなたのアクセスキーID"
export AWS_SECRET_ACCESS_KEY="あなたのシークレットアクセスキー"
=(イコール)の右側の文字列は、あなたのキーに置き換えてくださいね。
これで次からモデルに画像を設定したら、アップロードした画像はAmazon S3に保存されるようになりました。意外と簡単だったのではないでしょうか?
実際にAmazon S3にデータを追加できるか試してみましょう。
Amazon S3に画像を登録する
実際にSkillモデルにデータを追加してみます。
フォームに情報を入力し、画像も追加して、作成ボタンを押します。
画像がちゃんとアップロードされていますね。念の為、ソースも確認して、Amazon S3から画像を取得しているか確認してみましょう。
srcがs3のアドレスになっています。Amazon S3のバケットの中を見ても、ちゃんと画像が登録されています。
NoCredentialsErrorが発生する場合
repl.itで作成していた際に、NoCredentialErrorが発生しました。このエラーはアクセスキーIDとシークレットアクセスキーが確認ができなかったということで発生しています。
環境変数からではなく、直接AWS_ACCESS_KEY_IDとAWS_SECRET_ACCESS_KEYに値を入れたら動いたので(あぶない!)、repl.itで環境変数を使うのがよくないのかもしれません。どちらにせよ、すぐにリセットされてしまいますし。
…というわけで今回の記事の内容を試す場合は、自分のPC環境でやった方が安心・安全だと思います(`・ω・´)
サンプルサイト
repl.itにここまでに作成した内容を残しておきます。真ん中の再生ボタンを押すと、今回作成した部分を確認できます。また、左側にあるCodeタブを選択すると、ファイル構成やファイルの内容を確認できます。
※ちゃんと動かしたい場合は、Fork/ダウンロードして、AWSキーの設定をして試してください。
ここまで読んでいただけたなら、”スキ”ボタンを押していただけると励みになります!(*´ー`*)ワクワク
この記事が気に入ったらサポートをしてみませんか?