9
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Nuxt&Django REST FrameworkでS3を使ってメディアを保存する

Posted at

前提

画像ファイルや映像ファイルといったメディアを直接DBに保存するのはSQLのパフォーマンス的に現実的に考えるとなかなかあり得ることではありません。

やはりS3のようなストレージサービスに預けてそのパスをDRFで読み込み→クライアントサイドで出力が一般的でしょう。

なので今回はNuxtで画像を伴ったデータを追加し、それらがきちんと出力されるまでの流れを書いていきます。

なお、既にDjangoのプロジェクト、AWSのアカウントは所持しているものとします。

私はここからダウンロードしたコードの設定ファイルを変えて実装しています。

環境

boto3==1.13.25
botocore==1.16.25
Django==3.0.7
django-cors-headers==3.2.1
django-storages==1.9.1
djangorestframework==3.11.0

導入

IAM

まずはIAMにアクセスしてS3にアクセスができるようなユーザーを作っておきましょう。
AWSのマネジメントコンソールにアクセスした際に出てくる検索バーにIAMと打ち込み、IAMのページにアクセスしてください。

スクリーンショット 2020-06-12 14.32.41.png

そこでユーザーのページからユーザーを追加するというというページにとび、そこで任意のユーザー名、プログラムによるアクセスにチェックを入れてアクセス権限のページへと進んでください。

スクリーンショット 2020-06-12 14.36.26.png

そこでユーザーをグループに追加を選び、その上で任意のグループ名、そして権限としてAmazonS3FullAccessのポリシーを割り当てます。

スクリーンショット 2020-06-12 14.40.36.png

スクリーンショット 2020-06-12 14.39.13.png

これで次のタグの追加(オプション)に進みますが、ここは無視して確認に進んで大丈夫です。

すると新しく追加された場合、ユーザー名とアクセスキー、そしてシークレットアクセスキーが表示されます。

こちらはあとで使いますので覚えておいてください。
ここまででIAMに関する部分は終わりです。

S3

次にS3でデータの保存先となるバケットを作成しましょう。

スクリーンショット 2020-06-09 12.06.39.png

S3にアクセスし、バケットを作成します。

スクリーンショット 2020-06-12 15.59.04.png

今回はひとまずこういった設定にしました。
パブリックアクセスをオフにして、残りの設定はひとまず無視してこのまま作成して大丈夫です。

ここまででひとまずS3の初期設定は終わりです。

Django

DjangoでS3にファイルを保存するために、

をインストールします。

$ pip install boto3 django-storages

Settings
To upload your media files to S3 set:

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
To allow django-admin.py collectstatic to automatically put your static files in your bucket set the following in your settings.py:

STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

AWS_ACCESS_KEY_ID
Your Amazon Web Services access key, as a string.
AWS_SECRET_ACCESS_KEY
Your Amazon Web Services secret access key, as a string.

Note

If AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set, boto3 internally looks up IAM credentials.

AWS_STORAGE_BUCKET_NAME
Your Amazon Web Services storage bucket name, as a string.

どうやらドキュメントをみたところ、以下が必須なようです。

settings.py
# Django-Storage
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

# AWS-Settings
AWS_ACCESS_KEY_ID = 'YOUR_AWS_ACCESS_KEY_ID'
AWS_SECRET_ACCESS_KEY = 'YOUR_AWS_SECRET_ACCESS_KEY'
AWS_STORAGE_BUCKET_NAME = 'nuxt-django'
AWS_LOCATION = 'static' # s3バケット上のベースとなるファイルパス

# STATIC-Files
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
STATIC_URL = 'https://%s/%s/' % (AWS_S3_CUSTOM_DOMAIN, AWS_LOCATION)
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]

こんな感じで設定しておいてください。

この後に

$ python manage.py collectstatic

を行うと・・・

164 static files copied.

といったようなメッセージが返ってきます。

実際にS3のバケットを見てみましょう。

スクリーンショット 2020-06-12 16.46.07.png

実際にstaticというフォルダ名で保存されていますね。
ここまででひとまずDjangoの設定は終わりました。

DRFの設定

これが必要かと思いきや実は冒頭のソースをそのまま使った場合ここまでの設定だけで終わりです。
なので今後Nuxt側でAPIを叩いたらメディアファイルは自動的にS3にアップロードされます。

例えば、こういう風に、クライアントサイドから画像を伴ったPOSTを受けると・・・

スクリーンショット 2020-06-12 17.25.11.png

スクリーンショット 2020-06-12 17.28.28.png

スクリーンショット 2020-06-12 17.28.43.png

こんな感じにアップロードされています。

ここまででひとまずメディアを保存することに成功したのでここで終わります。
お疲れ様でした。

この記事が誰かの役に立てば幸いです。

9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?