Problem uploading images using ImageField in Django on Heroku - django

I have an ImageField and I'm also using AWS S3.
Locally whenever I upload an image this works perfectly and I am able to upload the image and view it.
However, when I try to upload an image on heroku I get this error:
expected string or bytes-like object
For my ImageField in my models.py it is:
image = models.ImageField(blank=False)
In settings.py I have:
AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME')
AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = None
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
AWS_S3_REGION_NAME = 'the location im using'
django_heroku.settings(locals())
So not quite sure how to fix it so it works in heroku like it does locally.
Thanks

I figured out my problem.
I didn't put my environment variables into heroku (the hosting service I am using). That is why it worked locally but not on heroku.
In the terminal I just had to do this for all the relevant environment variables:
heroku config:set GITHUB_USERNAME="joesmith"
More information here

Related

django storages breaks the admin staticfiles

I tried moving from local static files to S3 using django-storages. I followed the documentation carefully but still there is no access to the static files.
In the local environment I have:
STATIC_URL = '/static/'
in the settings.py and everything works fine.
when I add all the S3 params as the documentation shows:
STATIC_URL = 'https://django-main.s3.amazonaws.com/'
ADMIN_MEDIA_PREFIX = 'https://django-main.s3.amazonaws.com/admin/' # tried with this and also without this
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3StaticStorage'
AWS_ACCESS_KEY_ID = '<AWS_ACCESS_KEY_ID>'
AWS_SECRET_ACCESS_KEY = '<AWS_SECRET_ACCESS_KEY>'
AWS_STORAGE_BUCKET_NAME = 'bucket-name'
I ran python manage.py collectstatic which seemed to work fine and uploaded the static files to the bucket.
but running the server and going to the admin page it looks like this:
which is because it doesn't have access to the static files. No error is thrown/shown
Any ideas?
EDIT:
So apperently I'm getting a forbbiden call:
but I changed my settings.py to:
AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
and made sure that access is available (put a breakpoint and downloaded a css file using boto3 from that bucket using these exact environment variables and still no solution
The issue was that the bucket read permissions were not public. Changing the permissions worked

Is this a problem Deploying Heroku before working in AWS?

I've deployed my site on Heroku with no problems. After that, I've uploaded my static and media folder to AWS and i get this error:
raise ImproperlyConfigured("Could not load Boto3's S3 bindings. %s" % e)
django.core.exceptions.ImproperlyConfigured: Could not load Boto3's S3 bindings.
No module named 'boto3'
I've installed everything, I've done pip freeze < requirements.text.
Please help me.
I had to replace following using python3
boto==2.45.0
With
boto3==1.4.4
In requirements/production.txt and push to heroku again.
I also had to replace
MEDIA_URL = 'https://s3.amazonaws.com/%s/media/' % AWS_STORAGE_BUCKET_NAME
STATIC_URL = 'https://s3.amazonaws.com/%s/static/' % AWS_STORAGE_BUCKET_NAME
with
MEDIA_URL = 'https://s3.amazonaws.com:443/%s/media/' % AWS_STORAGE_BUCKET_NAME
STATIC_URL = 'https://s3.amazonaws.com:443/%s/static/' % AWS_STORAGE_BUCKET_NAME
in config/settings/production.py. But not sure it this last thing is just my problem

Django static files using s3

I am having problems using an s3 bucket for my sites static files. Currently using django-storages and boto3.
In my setting.py I have:
AWS_ACCESS_KEY_ID = env("AWS_ACCESS_KEY_ID")
AWS_SECRET_ACCESS_KEY = env("AWS_SECRET_ACCESS_KEY")
AWS_STORAGE_BUCKET_NAME = env("AWS_STORAGE_BUCKET_NAME")
AWS_S3_FILE_OVERWITE = False
AWS_DEFAULT_ACL = None
AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com'
AWS_LOCATION = 'static'
STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{AWS_LOCATION}/'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
Running collectstatic sends static files to the s3 bucket successfully, but the static urls in my templates do not update.
I am using apache2 and have not changed the .conf file, do I need to?
Any help would be gratefully recieved
When you say but the static urls in my templates do not update. what did you meant by that, can you try printing the static_url in settings and see if you are getting url what you are expecting, and can you share your template where you are accessing this.

Media uploads django mezzanine giving HTTP Error 500

I'm trying to setup django and the cms package mezzanine to use amazon s3 storage using django-storages and django-s3-folder-storage. All works well in the sense that I can use collectstatic without issue and upload my files to amazon, and also images get served correctly as does css/js.
However if a user tries to upload an image to the media-library or as a featured-image for a blog post. I get simply HTTP Error in the browser and POST /admin/media-library/upload_file/ HTTP/1.1" 500 146580 in the console. This is with DEBUG=True set, so I'm surprised there is not more of a trace/feedback.
I'm not sure what to do to fix or even begin debugging why this is occurring, anyone help?
My relevant settings.py are:
AWS_STORAGE_BUCKET_NAME = 'my_bucket'
AWS_SECRET_ACCESS_KEY = 'my_key'
AWS_ACCESS_KEY_ID = 'my_id'
AWS_PRELOAD_METADATA = True
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/'
I had the same problem. What the problem turned out to be for me was in my setup I needed to change the permissions on this directory (and all its sub-directories) to be owned by the user used by my nginx.conf:
/var/lib/nginx
To correct this I did:
sudo chown -R <myuser>:<myuser> /var/lib/nginx
Where myuser is the nginx user specified in nginx.conf.
Think images you are uploading are placed in a temporary folder in there before reaching Amazon S3 and this temporary folder doesn't have the correct permissions to allow this.
What got me on the right track to fix this was I changed debug to DEBUG = True and then when I got the 500 error in my error logs I saw:
[crit] 26489#0: *374 open() "/var/lib/nginx/tmp/client_body/0000000050" failed (13: Permission denied),
Also have a look at this:
nginx 500 error, permission denied for tmp folder

How to change private S3 bucket setting to serve images as http (not https) with django-storages?

I am using boto with django-storages to upload images directly to S3 from my django form. Everything is ok, except image url is https. I think having https is overkill and not required for media files. How do I change the setting to serve images as http? Went through documentation, couldn't find right settings.
My AWS setting is as follows.
AWS_ACCESS_KEY_ID = 'xxx'
AWS_SECRET_ACCESS_KEY = 'xxx'
AWS_STORAGE_BUCKET_NAME = 'xxx'
AWS_DEFAULT_ACL = 'private'
AWS_LOCATION = '/media/'
Thanks in advance.
Ok, I read the django-storages source code, and it's there.
django-storages on github
All I need to do is set SECURE_URLS to false, like this.
AWS_S3_SECURE_URLS = False
:)