Connecting S3-compatible storage to serve static files is becoming increasingly popular.
In this article we look at connecting S3 storage from Yandex.Cloud to a Django project. We'll skip creating a Yandex.Cloud account, enabling the Object Storage service, getting access keys and creating a bucket — we assume that's already done.
Installing packages
First, let's install the django-storages and boto3 packages:
pip install django-storages
pip install boto3Storage classes
Create a file s3_storage.py in the same folder as settings.py — it will describe our custom storage classes. Add the following code to it:
from storages.backends.s3boto3 import S3Boto3Storage
class MediaStorage(S3Boto3Storage):
bucket_name = 'my_bucket'
location = 'media'
class StaticStorage(S3Boto3Storage):
bucket_name = 'my_bucket'
location = 'static'Here we create two classes: MediaStorage describes storage for media files, and StaticStorage — for static files. Both use the same bucket my_bucket, but files are kept in two different folders — media and static.
settings.py configuration
Add the following parameters to the settings.py file:
DEFAULT_FILE_STORAGE = 'my_app.s3_storage.MediaStorage'
STATICFILES_STORAGE = 'my_app.s3_storage.StaticStorage'
AWS_S3_ENDPOINT_URL = 'https://storage.yandexcloud.net'
AWS_S3_ACCESS_KEY_ID = os.getenv('AWS_S3_ACCESS_KEY_ID')
AWS_S3_SECRET_ACCESS_KEY = os.getenv('AWS_S3_SECRET_ACCESS_KEY')
AWS_QUERYSTRING_AUTH = FalseAdd the storages app to the INSTALLED_APPS list:
INSTALLED_APPS = [
...,
'storages',
]The DEFAULT_FILE_STORAGE and STATICFILES_STORAGE variables tell Django which classes to use for handling media and static files respectively.
AWS_S3_ENDPOINT_URL sets the Yandex.Cloud URL for serving files. AWS_S3_ACCESS_KEY_ID and AWS_S3_SECRET_ACCESS_KEY hold the unique identifier and secret key for accessing the storage API.
The AWS_QUERYSTRING_AUTH variable controls whether authentication query parameters are added when accessing S3. It makes sense to set it to False if the bucket is public.
Uploading files
The configuration is done. First, let's push static files to the S3 bucket with the collectstatic command:
python manage.py collectstaticWait for the transfer to finish. To test media files, create an object whose model has an ImageField or FileField, and attach files to it — after saving, they should appear in the S3 bucket.