Using Amazon Web Services (AWS) S3 For storing static and media files for a Django Project.
-
Create AWS Account: here
-
Create AWS User Credentials
-
Navigate to IAM Users
-
Select
Create New Users
-
Enter
awsbean
as a username (or whatever you prefer) -
Ensure
Generate an access key for each user
is selected. -
Select
Download credentials
and keep them safe. -
Open the
credentials.csv
file that was just downloaded/created -
Note the
Access Key Id
andSecret Access Key
as they are needed for a future step. These will be referred to as<your_access_key_id>
and<your_secret_access_key>
-
-
Create new S3 Bucket
- Navigate to S3 through the Console or this Link
- Click
Create Bucket
- Create a unique
Bucket Name
such asyour-project-bucket
or any other name you choose. - Select
Region
relative to your primary users' location. - Click
Create
Make note of the
Bucket Name
you created here. It will replace<your_bucket_name>
below. -
Add Default Access Policies to your IAM User:
- Navigate to the user's account such as: https://console.aws.amazon.com/iam/home?region=us-west-2#users/awsbean
- Click on
Permissions
tab. - Click on
Attach Policies
and add any policies you'd like to give this user access to.
This step, we're not going to do. Instead, we are going to limit what our IAM User has access to in our AWS account. So onto the next step.
-
Add Custom Permissions to your IAM User
-
Navigate to the user's account such as: https://console.aws.amazon.com/iam/home?region=us-west-2#users/awsbean
-
Click on
Permissions
tab. -
Click tab for
Inline Policies
and create a new one. -
Select
Custom Policy
-
Set
Policy Name
toS3Django
(or any name you decide) -
Set
Policy Document
to, make note of the<your_bucket_name>
as we just set this bucket name:{ "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation", "s3:ListBucketMultipartUploads", "s3:ListBucketVersions" ], "Resource": "arn:aws:s3:::<your_bucket_name>" }, { "Effect": "Allow", "Action": [ "s3:*Object*", "s3:ListMultipartUploadParts", "s3:AbortMultipartUpload" ], "Resource": "arn:aws:s3:::<your_bucket_name>/*" } ] }
-
The
Action
s that we choose to set are based on what we want this user to be able to do. The line"s3:*Object*",
will handle a lot of our permissions for handling objects for the specified bucket within theRecourse
Value.
-
-
Django Setup
This assumes you have a
Django project
already started.-
Pip downloads:
pip install boto django-storages-redux
-
Add
'storages',
toINSTALLED_APPS
in your Django Settings (such as insettings.py
) -
Run
python manage.py migrate
to ensuredjango-storages-redux
is installed. Django Storage Redux (docs) is a updated version of Django Storage (docs) and should be considered as a viable replacement. -
In your Django configuration folder where
settings.py
andurls.py
are, create a new file calledutils.py
-
In
utils.py
add the following:from storages.backends.s3boto import S3BotoStorage StaticRootS3BotoStorage = lambda: S3BotoStorage(location='static') MediaRootS3BotoStorage = lambda: S3BotoStorage(location='media')
-
In your
settings.py
add the following:AWS_ACCESS_KEY_ID = "<your_access_key_id>" AWS_SECRET_ACCESS_KEY = "<your_secret_access_key>" AWS_FILE_EXPIRE = 200 AWS_PRELOAD_METADATA = True AWS_QUERYSTRING_AUTH = True DEFAULT_FILE_STORAGE = '<your-project>.utils.MediaRootS3BotoStorage' STATICFILES_STORAGE = '<your-project>.utils.StaticRootS3BotoStorage' AWS_STORAGE_BUCKET_NAME = '<your_bucket_name>' S3DIRECT_REGION = 'us-west-2' S3_URL = '//%s.s3.amazonaws.com/' % AWS_STORAGE_BUCKET_NAME MEDIA_URL = '//%s.s3.amazonaws.com/media/' % AWS_STORAGE_BUCKET_NAME MEDIA_ROOT = MEDIA_URL STATIC_URL = S3_URL + 'static/' ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/' import datetime two_months = datetime.timedelta(days=61) date_two_months_later = datetime.date.today() + two_months expires = date_two_months_later.strftime("%A, %d %B %Y 20:00:00 GMT") AWS_HEADERS = { 'Expires': expires, 'Cache-Control': 'max-age=%d' % (int(two_months.total_seconds()), ), }
-
Run
python manage.py collectstatic
and you should be all setup.
-
Subscribe on our YouTube Channel and join us for more in-depth tutorials on Django development.
Cheers!