If your application supports user-uploaded files (such as media uploads), you’ll need a storage solution separate from the application’s local filesystem. Sevalla’s object storage is ideal for securely storing and serving these files. Static files can also be delivered from object storage if desired, though this is optional and depends on your application’s setup and performance needs.
Start by creating an object storage on Sevalla. Settings contains all the values needed for your storages settings.
Install
Before your media files can be uploaded to object storage, the django-storages library must be added to your dependencies. Sevalla’s object storage is S3-compatible, so the s3 extra should be included when installing, which installs boto3 for you.
pip install django-storages[s3]
pip freeze > requirements.txt
Settings
You need to add the storages settings to settings.py. Both the signature version of s3v4 and the storages.backends.s3.S3Storage are necessary for Django to properly use the object storage.
You can use your preferred method for defining configuration values for access_key, secret_key, bucket_name, and endpoint_url. django-environ is used for this example.
STORAGES = {
"default": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {
"access_key": env("MEDIA_BUCKET_ACCESS_KEY"),
"secret_key": env("MEDIA_BUCKET_SECRET_KEY"),
"bucket_name": env("MEDIA_BUCKET_NAME"),
"endpoint_url": env("MEDIA_BUCKET_ENDPOINT_URL"),
"signature_version": "s3v4"
}
}
}
If you would like your media bucket to be publicly accessible, in the object storage Settings, click Enable public access.
Then you’ll need to add the custom_domain to your storages settings dictionary.
STORAGES = { #
"default": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {
"access_key": env("MEDIA_BUCKET_ACCESS_KEY"),
"secret_key": env("MEDIA_BUCKET_SECRET_KEY"),
"bucket_name": env("MEDIA_BUCKET_NAME"),
"endpoint_url": env("MEDIA_BUCKET_ENDPOINT_URL"),
"custom_domain": env("MEDIA_BUCKET_DOMAIN"),
"signature_version": "s3v4"
}
}
}
Once your app is restarted with the configuration values loaded, it will place any user-uploaded files into object storage instead of the file system.
Static Files
Static files can also be placed in an object storage instead of being served directly from your app with WhiteNoise. If you will have both media files and static files served from an object store, you should use a separate object storage for each type.
Start by creating a new object storage on Sevalla. To fully support all the static files used for the admin dashboard, you should make your static file object store public.
Settings
Add separate settings for staticfiles in the STORAGES dictionary.
STORAGES = {
"default": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {
"access_key": env("MEDIA_BUCKET_ACCESS_KEY"),
"secret_key": env("MEDIA_BUCKET_SECRET_KEY"),
"bucket_name": env("MEDIA_BUCKET_NAME"),
"endpoint_url": env("MEDIA_BUCKET_ENDPOINT_URL"),
"signature_version": "s3v4"
}
},
"staticfiles": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {
"access_key": env("STATIC_BUCKET_ACCESS_KEY"),
"secret_key": env("STATIC_BUCKET_SECRET_KEY"),
"bucket_name": env("STATIC_BUCKET_NAME"),
"endpoint_url": env("STATIC_BUCKET_ENDPOINT_URL"),
"custom_domain": env("STATIC_BUCKET_DOMAIN"),
"signature_version": "s3v4"
}
}
}
Django doesn’t use the STATIC_URL setting when STORAGES is set but still requires it, so for clarity, you may want to add the proper STATIC_URL to settings.py .
STATIC_URL = 'static/'
STATIC_URL = f'{env("STATIC_BUCKET_DOMAIN")}/'
You can then remove WhiteNoise, if you have it.
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
Your static files will now be uploaded to the bucket when the collectstatic command is run.
The collectstatic command will take longer to run because the static files need to be uploaded to the object storage.