django set multiple allowed hosts - django

I'm trying to set multiple allowed hosts in django
I have setting configured in production settings production.py as
ALLOWED_HOSTS = env('DJANGO_ALLOWED_HOSTS')
which I can then set on heroku with:
heroku config:set 'DJANGO_ALLOWED_HOSTS' = 'www.example.com'
However how can I add multiple hosts via this method?

You can provide a delimiter then split the string in django
ALLOWED_HOSTS = env('DJANGO_ALLOWED_HOSTS').split(',')
heroku config:set 'DJANGO_ALLOWED_HOSTS' = 'www.example.com,foo.com'

To define multiple values for allowed hosts in settings.py file use like:
ALLOWED_HOSTS = ['000.08.10.11','111.22.33.44','www.abcdefgh.com']

Related

How does Django manage different subdomains on one Django project?

I want my Django project to be accessible at many different endpoints. For one app, I want it accessible at app.domain.com and for another app I want it accessible at dashboard.domain.com. How can I achieve this? I am using AWS Elastic Beanstalk and Route 53.
I tried looking at Django's djangoproject.com and their Github repo, as they do this. However, I couldn't figure it out. Thanks!
You can define two settings.py file, with two associated urls.py files :
app_settings.py
from my_project.settings import *
ROOT_URLCONF = 'my_project.app_urls'
ALLOWED_HOSTS = ['app.domain.com']
dashboard_settings.py
from my_project.settings import *
ROOT_URLCONF = 'my_project.dashboard_urls'
ALLOWED_HOSTS = ['dashboard.domain.com']
Define your urls for each website respectively in my_project/app_urls.py and my_project/dashboard_urls.py
Then start two instances of your django project (with uwsgi, gunicorn ou whatever you use) with those two distinct settings files (using DJANGO_SETTINGS_MODULE environment variable for example).
This way, both instances shares the same codebase but exposes distinct urls.
For example, using uwsgi, you could have those two files (with distinct ports) :
app.ini
[uwsgi]
http = 127.0.0.1:8001
module = my_project.wsgi
processes = 4
threads = 2
pidfile = app.pid
env = DJANGO_SETTINGS_MODULE=my_project.app_settings
dashboard.ini
[uwsgi]
http = 127.0.0.1:8002
module = my_project.wsgi
processes = 4
threads = 2
pidfile = app.pid
env = DJANGO_SETTINGS_MODULE=my_project.dashboard_settings

django: how to load the static files with hash/md5 appending correctly?

using Django 3
I followed the Django Doc
https://docs.djangoproject.com/en/3.0/ref/contrib/staticfiles/#manifeststaticfilesstorage
to export my static files with a hash appending.
settings.py production
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
static_root folder (output)
static_root/
staticfiles.json
static_root/css/
project_styles.87c2920e7bc3.css
project_styles.css
everything is collected correctly.
Afterwards i uploaded everything to my apache static server.
And i set off / comment the STATICFILES_STORAGE . That is how i understand the Doc´s? If i leave this setting on in production i get an 500 Error.
settings.py production
# STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
After restarting my Django app in production, my site is still loading project_styles.css but not the hash Version project_styles.87c2920e7bc3.css in my browser. Even if i delete project_styles.css Django will not serve the hash version.
Question
Did i miss some settings in the settings.py in production mode?
In the Doc´s they mention to set STATICFILES_STORAGE = django.contrib.staticfiles.storage.StaticFilesStorage but it shows no difference. And as it is mentioned it´s only for testing.
What i have to do to load the correct static hash version in production? do i have to set something in my templates, so that django will look into the json file for the correct hash version? Or do i have to name the hash file?
Alright, the Problem was that i wanted two different STATIC_ROOT Paths. One for Development and one for Production, because i want all my Development stuff in one Project folder. Because if you collectstatic with the STATIC_ROOT of your apache server, django will export it for instance into c:/var/www/your/server/static while i wanted it to c:/webprojects/myproject_1/static_root_exports and later upload these files on my server separately.
So i set two different Path depending on DEV_STATIC off / on in my django-environ file. Django will set the correct Path.
.env
DEBUG=off
# --- applies media server & sets MEDIA_ROOT & STATIC_ROOT
DEV_STATIC=on
<...>
STATIC_ROOT_DEV=static_root_exports
STATIC_ROOT_PROD=/var/www/myUserName/html/myproject_assets/static
<...>
setting.py
# -- Set for Hash
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
# --- STATIC_ROOT
if DEV_STATIC == True:
STATIC_ROOT = SERVER_DIR.joinpath(env('STATIC_ROOT_DEV'))
else:
STATIC_ROOT = env('STATIC_ROOT_PROD')

Dotenv Doesn't Handle Multiple Hosts in ALLOWED_HOSTS

In my production setting.py file I have:
from dotenv import load_dotenv
load_dotenv(override=True)
DEBUG = os.getenv('DEBUG')
#ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS")
ALLOWED_HOSTS = ['example.com', 'www.example.com']
In my .env file in production, I have
DEBUG=False
ALLOWED_HOSTS=['www.example.com', 'example.com']
If I switch the commented out line in settings, I get an error saying url may not be in the allowed hosts. I have a number of other definitions in the .env file that work fine although I'm not sure about debug. I've tried all sorts of combinations on the ALLOWED_HOSTS and get the same error. In development I have:
ALLOWED_HOSTS='localhost'
That setting works fine. Any idea what I'm doing wrong?
I found a portion of answer here. Then I did that :
#setting.py
ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS").split(' ')
#.env
ALLOWED_HOSTS = domain1 domain2 domain3 domain4
And it works.
It looks like you are not loading the .env file properly. Try:
project_folder = os.path.expanduser('~/my-project-dir') # adjust as appropriate
load_dotenv(os.path.join(project_folder, '.env'))
ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS")
Documentation: https://help.pythonanywhere.com/pages/environment-variables-for-web-apps/

After deploying to heroku

I have a webapp which is not yet complete but I recently deployed it to heroku. It uses:
Django
Rest-framework
Reactjs
Now, I have deployed deploy-heroku branch of my project to master of heroku.
The only difference between my project's master branch and deploy-heroku branch is that I have made additional changes in settings.py (adding prostgre sql settings and all) in the deploy-heroku branch.
I want to add more features to my webapp so should I work on master and later copy-paste those changes to deploy-heroku. This seems redundant !! Is there any other better way to do this?
You could just let Heroku automatic deploy on master and use a ".env" file with Django-environ (https://github.com/joke2k/django-environ) to change your settings.py. You should be able to create a local Django setting and a Heroku prod setting.
Example :
.env :
DEBUG=on
SECRET_KEY=your-secret-key
DATABASE_URL=psql://urser:un-githubbedpassword#127.0.0.1:8458/database
SQLITE_URL=sqlite:///my-local-sqlite.db
setting.py:
import environ
env = environ.Env(
# set casting, default value
DEBUG=(bool, False)
)
# reading .env file
environ.Env.read_env()
# False if not in os.environ
DEBUG = env('DEBUG')
# Raises django's ImproperlyConfigured exception if SECRET_KEY not in os.environ
SECRET_KEY = env('SECRET_KEY')
# Parse database connection url strings like psql://user:pass#127.0.0.1:8458/db
DATABASES = {
# read os.environ['DATABASE_URL'] and raises ImproperlyConfigured exception if not found
'default': env.db(),
# read os.environ['SQLITE_URL']
'extra': env.db('SQLITE_URL', default='sqlite:////tmp/my-tmp-sqlite.db')
}
Don't forget to add the .env file to your .gitignore and to update your Heroku environment variables in your app -> settings -> Reveal config vars
You can merge branches.
Here is a good explanation of how it works

How to use S3 for Production on Heroku and local static css for development?

I have just installed Grunt in my Django app. In my blogengine app I have the folder: assets/css/global.scss. Grunt minifies this .scss file to static/css/global.css.
I am still developing the app locally. I have been running grunt sass and watch to minify the scss file to css as I'm working on it.
However, I've set the static url, etc to be my Amazon S3 bucket. This means when I run collectstatic, I have to wait ages for it to upload to S3 so I can see my changes.
I am wanting to eventually deploy this to Heroku, but in the meantime, how do I set my static content to work locally and setup production settings to use S3?
This is in settings.py:
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.6/howto/static-files/
STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
AWS_ACCESS_KEY_ID = 'XXXXXXXXXXXXXX'
AWS_SECRET_ACCESS_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'
AWS_STORAGE_BUCKET_NAME = 'ingledow'
STATIC_URL = 'http://ingledow.s3.amazonaws.com/'
You could mess with the DEBUG settings. In local development, set DEBUG to True, and Django will handle serving all the static files. Once you push to production, set DEBUG to False and the S3 settings will kick in. You could have different settings files or you could set an environment variable both locally and on Heroku and call it in your settings (i.e.: `DEBUG = os.environ['DEBUG'].
In your bashrc, set a environment flag:
alias DJANGO_ENV=local
(Alternatively, just do this in your local shell: export DJANGO_ENV=local)
Then in settings.py:
import os
if os.environ.get( 'DJANGO_ENV', '' ) == 'local':
# SETUP LOCAL SETTINGS
else:
STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
AWS_ACCESS_KEY_ID = 'XXXXXXXXXXXXXX'
AWS_SECRET_ACCESS_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'
AWS_STORAGE_BUCKET_NAME = 'ingledow'
STATIC_URL = 'http://ingledow.s3.amazonaws.com/'
Turn off the local settings when doing pushstatic (eg. "unset DJANGO_ENV"). On production (ie. Heroku), you won't have the DJANGO_ENV system variable, so it will default to AWS files.