PublicS3BotoStorage (where are you using this in your settings.py?)
Some questions:
1) Why do you define
AWS_SECRET_KEY = os.environ['AWS_SECRET_KEY']
AWS_SECRET_ACCESS_KEY = AWS_SECRET_KEY
and not just
AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_KEY']
2) What is the difference between
AWS_BUCKET_NAME and AWS_STORAGE_BUCKET_NAME here? and why
do define 'AWS_STORAGE_BUCKET_NAME' twice? (just a typo?)
3) You define DEFAULT_FILE_STORAGE = 's3_folder_storage.s3.DefaultStorage'
and STATICFILES_STORAGE = 's3_folder_storage.s3.StaticStorage'. Are these the locations
of your custom storage classes DefaultStorage and StaticStorage? How are they related to
to the PublicS3BotoStorage class from the bug fix? (assuming they are)
4) Why are MEDIA_ROOT and MEDIA_URL empty?
These considerations lead me to try and mimic your settings with
########################################
# Attempt fix from mezzanine users group
########################################
#
# AMAZON - AWS
# S3 config
AWS_ACCESS_KEY_ID="myid"
AWS_SECRET_ACCESS_KEY="myaccesskey"
AWS_STORAGE_BUCKET_NAME = 'my_bucket'
AWS_BUCKET_NAME = 'my_bucket'
AWS_QUERYSTRING_AUTH = False
AWS_S3_SECURE_URLS = False
AWS_S3_ENCRYPTION = False
from boto.s3.connection import ProtocolIndependentOrdinaryCallingFormat
AWS_S3_CALLING_FORMAT = ProtocolIndependentOrdinaryCallingFormat()
DEFAULT_FILE_STORAGE = 'mystorages.PublicS3BotoStorage'
DEFAULT_S3_PATH = "media"
MEDIA_ROOT = ''
MEDIA_URL = ''
STATICFILES_STORAGE = 'mystorages.PublicS3BotoStorage'
STATIC_S3_PATH = "static"
STATIC_ROOT = "/%s/" % STATIC_S3_PATH
STATIC_URL = '//s3.amazonaws.com/%s/static/' % AWS_STORAGE_BUCKET_NAME
ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/'
Notice in particular I use STATICFILES_STORAGE = 'mystorages.PublicS3BotoStorage'where mystorages.py is defined as in my link above (i.e. the bug fix subclass defined in there).
1) Why do you define
AWS_SECRET_KEY = os.environ['AWS_SECRET_KEY']
AWS_SECRET_ACCESS_KEY = AWS_SECRET_KEY
and not just
AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_KEY']
Legacy testing crap code basically (a poor understanding of settings). I updated the settings to remove duplicates and create clarity (see end of this post). Helping you helps me clean up my code :)
2) What is the difference between
AWS_BUCKET_NAME and AWS_STORAGE_BUCKET_NAME here? and why
do define 'AWS_STORAGE_BUCKET_NAME' twice? (just a typo?)
Same answer as #1.
3) You define DEFAULT_FILE_STORAGE = 's3_folder_storage.s3.DefaultStorage'
and STATICFILES_STORAGE = 's3_folder_storage.s3.StaticStorage'. Are these the locations
of your custom storage classes DefaultStorage and StaticStorage? How are they related to
to the PublicS3BotoStorage class from the bug fix? (assuming they are)
Yes, these are the custom classes. I highly suggest using Django-folder-storages, which is a small wrapper around storeages that sets up the custom static and media folders. This way you do not have to write your own. Here is a link to the plugin. If you are using PIP it's easy to install.
https://github.com/jamstooks/django-s3-folder-storage
4) Why are MEDIA_ROOT and MEDIA_URL empty?
Because MEDIA_URL will be prepended to media URL's when we don't need it to. The entire URL will be generated by Storages and we don't need the MEDIA_URL prepended. Most templates do something like this to generate a URL:
{{ MEDIA_URL }}{% thumbnail selected_landing_page.featured_image 665 400 %}That would prepend the MEDIA_URL and give you urls that look like:
http://someurl/image.pnghttp://anotherurl/some.png
"PublicS3BotoStorage' object has no attribute 'isdir'"
This issue is solved by using Django Folder Storage per #3. I tried rolling my own, but was met with this error every time. I don't know why because I literally copied his code directly and couldn't get it to work. IF you solve this issue let me know. I think it might have to do with the order of when the app is registered. If you make your custom class a new module and register it before your application then it would likely work. I never tried it because Django FOlder Storage worked fine.Here are my cleaned up settings:
AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID']
# Enable S3 deployment only if we have the AWS keys
S3_DEPLOYMENT=AWS_ACCESS_KEY_ID is not None
if S3_DEPLOYMENT:
AWS_STORAGE_BUCKET_NAME = os.environ['AWS_STORAGE_BUCKET_NAME']
AWS_QUERYSTRING_AUTH = False
AWS_S3_SECURE_URLS = False
AWS_S3_ENCRYPTION = False
from boto.s3.connection import ProtocolIndependentOrdinaryCallingFormat
AWS_S3_CALLING_FORMAT = ProtocolIndependentOrdinaryCallingFormat()
DEFAULT_FILE_STORAGE = 's3_folder_storage.s3.DefaultStorage'
DEFAULT_S3_PATH = "media"
MEDIA_ROOT = ''
MEDIA_URL = ''
STATICFILES_STORAGE = 's3_folder_storage.s3.StaticStorage'
STATIC_S3_PATH = "static"
STATIC_ROOT = "/%s/" % STATIC_S3_PATH
STATIC_URL = '//s3.amazonaws.com/%s/static/' % AWS_STORAGE_BUCKET_NAME
ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/'
else:
ALLOWED_HOSTS = ['*.YOUR_DOMAIN.com',,'www.YOUR_DOMAIN.com', '.compute-1.amazonaws.com']
EC2_PRIVATE_IP = None
try:
EC2_PRIVATE_IP = requests.get('http://169.254.169.254/latest/meta-data/local-ipv4', timeout=0.01).text
except requests.exceptions.RequestException:
logger.info("EC2 private IP addition to allowed hosts failed to resolve")
pass
if EC2_PRIVATE_IP:
ALLOWED_HOSTS.append(EC2_PRIVATE_IP)