Django
django-storages is the canonical way to back Django's MEDIA and STATIC files with S3-compatible storage. It wraps boto3 and integrates cleanly with Django's DEFAULT_FILE_STORAGE and STATICFILES_STORAGE settings.
Install
pip install django-storages[s3] boto3
Configure
import os
INSTALLED_APPS = [
# ...
'storages',
]
# Filebase credentials
AWS_ACCESS_KEY_ID = os.environ['FILEBASE_KEY']
AWS_SECRET_ACCESS_KEY = os.environ['FILEBASE_SECRET']
AWS_S3_REGION_NAME = 'auto'
AWS_S3_ENDPOINT_URL = 'https://s3.filebase.io'
AWS_S3_ADDRESSING_STYLE = 'path'
AWS_S3_SIGNATURE_VERSION = 's3v4'
# Public bucket settings
AWS_STORAGE_BUCKET_NAME = 'my-django-app-media'
AWS_DEFAULT_ACL = 'public-read'
AWS_S3_FILE_OVERWRITE = False
AWS_QUERYSTRING_AUTH = False # don't sign public URLs
AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.filebase.io'
# Use Filebase for media uploads
DEFAULT_FILE_STORAGE = 'storages.backends.s3.S3Storage'
# (Optional) also use Filebase for collected static files
STATICFILES_STORAGE = 'storages.backends.s3.S3Storage'
STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/static/'
MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/media/'
AWS_S3_CUSTOM_DOMAIN makes Django generate URLs like https://my-django-app-media.s3.filebase.io/media/uploads/photo.jpg, served by the Filebase CDN.
Use it from a model
from django.db import models
class Photo(models.Model):
image = models.ImageField(upload_to='photos/')
caption = models.CharField(max_length=200, blank=True)
When a user submits a form with an ImageField, Django uploads the file to Filebase under photos/<filename> and stores the path in the database.
Private media with pre-signed URLs
If your media is sensitive (user-uploaded documents, paid content), keep the bucket private and serve pre-signed URLs:
AWS_DEFAULT_ACL = 'private'
AWS_QUERYSTRING_AUTH = True # sign URLs
AWS_QUERYSTRING_EXPIRE = 3600 # 1 hour
Now Django's <img src="{{ obj.image.url }}"> produces a pre-signed URL that expires after an hour.
Multiple storage backends
For a public assets bucket and a private media bucket:
STORAGES = {
'default': {
'BACKEND': 'storages.backends.s3.S3Storage',
'OPTIONS': {
'bucket_name': 'my-app-media',
'default_acl': 'private',
'querystring_auth': True,
},
},
'staticfiles': {
'BACKEND': 'storages.backends.s3.S3Storage',
'OPTIONS': {
'bucket_name': 'my-app-static',
'default_acl': 'public-read',
'querystring_auth': False,
'custom_domain': 'my-app-static.s3.filebase.io',
},
},
}
(Django 4.2+ syntax; older versions use DEFAULT_FILE_STORAGE and STATICFILES_STORAGE separately.)
Run collectstatic
Once configured, manage.py collectstatic uploads your static files straight to Filebase:
python manage.py collectstatic --noinput
What's next
- AWS SDK for Python (boto3) for direct API access
- CDN and caching
- Browser uploads recipe for direct-to-S3 uploads from your frontend