はじめに
本記事では、Djangoを使ってAWS S3(Amazon Simple Storage Service)に画像をアップロードする方法を解説します。AWS S3はスケーラブルなオブジェクトストレージサービスで、メディアファイルの保存に最適です。
これまでは開発環境で画像をローカルに保存して開発してきましたが、いざ本番環境に移行しようとした際に、ローカルにある画像をS3へアップロードする必要が生じます。このような場合に役立つ情報が少ないため、この記事を執筆しました。
必要なもの
- Djangoプロジェクト
- AWSアカウント
- boto3ライブラリ
- django-storagesパッケージ
1. AWS S3の設定
- AWS S3バケットの作成:
AWSコンソールにログインし、S3バケットを作成します。バケット名(例:my-bucket-name
)を決定し、適切なリージョンを選択します。 - IAMユーザーの作成と権限設定:
S3にアクセスできるIAMユーザーを作成します。AmazonS3FullAccess
のポリシーをアタッチします。アクセスキーIDとシークレットアクセスキーを取得します。
2. Djangoプロジェクトの準備
- 必要なパッケージのインストール:
pip install boto3 django-storages
- Djangoアプリケーションの設定: a. プロジェクトディレクトリに
.env
ファイルを作成し、AWSの認証情報を記載します。
AWS_ACCESS_KEY_ID=your_access_key_id
AWS_SECRET_ACCESS_KEY=your_secret_access_key
b. settings.py
を編集して、AWS S3を使う設定を追加します。
# settings.py
import os
from storages.backends.s3boto3 import S3Boto3Storage
from tempfile import SpooledTemporaryFile
class CustomS3Boto3Storage(S3Boto3Storage):
def _save(self, name, content):
content.seek(0, os.SEEK_SET)
with SpooledTemporaryFile() as content_autoclose:
content_autoclose.write(content.read())
return super(CustomS3Boto3Storage, self)._save(name, content_autoclose)
AWS_ACCESS_KEY_ID = 'AWS_ACCESS_KEY_ID'
AWS_SECRET_ACCESS_KEY = 'AWS_SECRET_ACCESS_KEY'
AWS_STORAGE_BUCKET_NAME = 'your-bucket-name'
AWS_S3_REGION_NAME = 'your-region-name' # 例: 'us-west-2' 'ap-northeast-1'
AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.{AWS_S3_REGION_NAME}.amazonaws.com'
AWS_S3_OBJECT_PARAMETERS = {
'CacheControl': 'max-age=86400',
}
AWS_LOCATION = 'static'
AWS_DEFAULT_ACL = None
STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{AWS_LOCATION}/'
MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/media/'
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
STATICFILES_STORAGE = 'config.settings.CustomS3Boto3Storage'
DEFAULT_FILE_STORAGE = 'config.settings.CustomS3Boto3Storage'
3. 画像のアップロード方法
- Djangoシェルを使って手動でアップロード:
python manage.py shell
シェル内で以下のコードを実行します:
from django.core.files.storage import default_storage
from django.conf import settings
import os
# ローカルの画像ディレクトリパス
local_image_directory = '/path/media/CACHE/images'
# S3の保存先ディレクトリパス
s3_image_directory = 'CACHE/images'
# ローカルの画像ディレクトリ内のファイルをS3にアップロード
for root, dirs, files in os.walk(local_image_directory):
for file in files:
local_file_path = os.path.join(root, file)
s3_file_path = os.path.join(s3_image_directory, os.path.relpath(local_file_path, local_image_directory))
with open(local_file_path, 'rb') as f:
default_storage.save(s3_file_path, f)
あとは通常通り投稿などからS3へ画像をアップロードします。