見出し画像

AWS×Django_staticファイルをS3に保存する #302日目

本番環境構築の知識を付けていくため、AWS×Djangoという軸で色々と試しています。今回はDjangoのstaticファイルをS3に設定する方法についてです。

以下の動画から学ばせていただきました。

今回はdjango-storagesとboto3というライブラリを利用してS3を操作しますが、django-storagesはS3以外にも以下のようなストレージサービスをホストできます。

Amazon S3
Apache Libcloud
Azure Storage
Digital Ocean
Dropbox
FTP
Google Cloud Storage
SFTP

公式ドキュメントはこちらです。


Djangoで簡易アプリを作る

この部分は動画でもコードが紹介されているので最小限の部分のみ落としておきます。モデルに保存した内容と画像をそのまま表示するだけのアプリです。

[models.py]
 
from django.db import models

class BlogPost(models.Model):
    title = models.CharField(max_length=255)
    body = models.TextField()
    image = models.ImageField(upload_to='blog_images/')

    def __str__(self):
        return self.title
[views.py]
 
from django.shortcuts import render
from .models import BlogPost

def home(request):
    return render(request, 'home.html', {'posts': BlogPost.objects.all()})


settings.pyにS3用の設定をする

こちらが今回のDjango側の肝になります。settings.pyに以下の設定を追加します。

[settings.py]
 
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog',           # 追加:今回のアプリ
    'storages',       # 追加:S3を活用するためのもの
]
 
 
# AWS S3 Settings

AWS_ACCESS_KEY_ID = 'XXXXXXXXXXXXXXXXXXXXX'

AWS_SECRET_ACCESS_KEY = 'YYYYYYYYYYYYYYYYYYYYY'

AWS_STORAGE_BUCKET_NAME = 'django-s3-test-bucket'

AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com'

AWS_DEFAULT_ACL = 'public-read'

AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400'
}

AWS_LOCATION = 'static'

AWS_QUERYSTRING_AUTH = False

AWS_HEADERS = {
    'Access-Control-Allow-Origin': '*',
}


# Static files (CSS, JavaScript, Images)

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

STATICFILES_STORAGE = 'storages.backends.s3boto3.S3StaticStorage'

STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/static/'

MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/media/'


「AWS_ACCESS_KEY_ID」
「AWS_SECRET_ACCESS_KEY」
「AWS_STORAGE_BUCKET_NAME」

上記3つはS3にバケットを作成することで記載できるようになります。
実際に設定してみます。


IAMユーザーとセキュリティグループを作成する

最初のステップとして、IAMユーザーとセキュリティグループを作成します。ここではdjango-media-userというユーザーと、django-s3-assetsというセキュリティグループを作成しました。

このセキュリティグループにはS3へのフルアクセス権を付与しています。


IAMユーザーのSecurity credentialsからアクセス情報を取得

settings.pyに記述する「AWS_ACCESS_KEY_ID」と「AWS_SECRET_ACCESS_KEY」をここで取得します。

SECRET_ACCESS_KEYは設定時にしか表示されないので、予め設定してあるキーを一度削除して、新たにACCESS_KEY_IDを設定し直します。

IAMユーザーのページからSecurity credentialsを開きます。そして×印を押して現状のACCESS_KEYを削除します。

削除ができたら新たなACCESS_KEYを作成します。

作成完了したタイミングのみSecret access keyが表示できるので、ここでキーをコピペしてsettings.pyに記述します。


S3にバケットを作成

次にいよいよS3バケットを作成します。
AWSのS3のBucketsにアクセスしてCreate bucketをクリックします。

バケットの設定は以下のようにしました。

これでCreate bucketをクリックすれば完了です。
settings.pyの「AWS_STORAGE_BUCKET_NAME」にここで設定したバケット名を記載します。


Djangoを動かしてみる

BlogPostモデルをマイグレードしてDjangoを動かしてみます。

$ python manage.py makemigrations && python manage.py migrate

$ python manage.py createsuperuser --username yuki

$ python manage.py runserver

この状態だとstaticがまだ機能していないので、UIが以下のように表示されます。

collectstaticすればOKです。

$ python manage.py collectstatic

You have requested to collect static files at the destination
location as specified in your settings.

This will overwrite existing files!
Are you sure you want to do this?

Type 'yes' to continue, or 'no' to cancel: yes

130 static files copied.

UIが機能します。


BlogPostモデルに画像を投稿する

管理画面から投稿してみます。

ブラウザで表示するとこうなります。

S3に画像が保存されているか確認します。
バケットを見るとstaticフォルダが作成されています。

staticフォルダに入ると「blog_images/」フォルダが作成されています。これはmodels.pyに定義している「upload_to='blog_images/'」」です。

ここから先ほどアップロードしたファイルを選択すると、以下のように表示されます。右上の「open」を押すとアップロードした画像が表示されます。


ここまでお読みいただきありがとうございました!


参考


この記事が気に入ったらサポートをしてみませんか?