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
awsbeanas a username (or whatever you prefer) -
Ensure
Generate an access key for each useris selected. -
Select
Download credentialsand keep them safe. -
Open the
credentials.csvfile that was just downloaded/created -
Note the
Access Key IdandSecret Access Keyas 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 Namesuch asyour-project-bucketor any other name you choose. - Select
Regionrelative to your primary users' location. - Click
Create
Make note of the
Bucket Nameyou 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
Permissionstab. - Click on
Attach Policiesand 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
Permissionstab. -
Click tab for
Inline Policiesand create a new one. -
Select
Custom Policy -
Set
Policy NametoS3Django(or any name you decide) -
Set
Policy Documentto, 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
Actions 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 theRecourseValue.
-
-
Django Setup
This assumes you have a
Django projectalready started.-
Pip downloads:
pip install boto django-storages-redux -
Add
'storages',toINSTALLED_APPSin your Django Settings (such as insettings.py) -
Run
python manage.py migrateto ensuredjango-storages-reduxis 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.pyandurls.pyare, create a new file calledutils.py -
In
utils.pyadd the following:from storages.backends.s3boto import S3BotoStorage StaticRootS3BotoStorage = lambda: S3BotoStorage(location='static') MediaRootS3BotoStorage = lambda: S3BotoStorage(location='media') -
In your
settings.pyadd 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 collectstaticand you should be all setup.
-
Subscribe on our YouTube Channel and join us for more in-depth tutorials on Django development.
Cheers!