86đź‘Ť
Update: django-configurations has been released which is probably a better option for most people than doing it manually.
If you would prefer to do things manually, my earlier answer still applies:
I have multiple settings files.
settings_local.py
– host-specific configuration, such as database name, file paths, etc.settings_development.py
– configuration used for development, e.g.DEBUG = True
.settings_production.py
– configuration used for production, e.g.SERVER_EMAIL
.
I tie these all together with a settings.py
file that firstly imports settings_local.py
, and then one of the other two. It decides which to load by two settings inside settings_local.py
– DEVELOPMENT_HOSTS
and PRODUCTION_HOSTS
. settings.py
calls platform.node()
to find the hostname of the machine it is running on, and then looks for that hostname in the lists, and loads the second settings file depending on which list it finds the hostname in.
That way, the only thing you really need to worry about is keeping the settings_local.py
file up to date with the host-specific configuration, and everything else is handled automatically.
Check out an example here.
26đź‘Ť
Personally, I use a single settings.py for the project, I just have it look up the hostname it’s on (my development machines have hostnames that start with “gabriel” so I just have this:
import socket
if socket.gethostname().startswith('gabriel'):
LIVEHOST = False
else:
LIVEHOST = True
then in other parts I have things like:
if LIVEHOST:
DEBUG = False
PREPEND_WWW = True
MEDIA_URL = 'http://static1.grsites.com/'
else:
DEBUG = True
PREPEND_WWW = False
MEDIA_URL = 'http://localhost:8000/static/'
and so on. A little bit less readable, but it works fine and saves having to juggle multiple settings files.
- [Django]-New url format in Django 1.9
- [Django]-Where is a good place to work on accounts/profile in Django with the Django registration app?
- [Django]-Bulk create model objects in django
25đź‘Ť
At the end of settings.py I have the following:
try:
from settings_local import *
except ImportError:
pass
This way if I want to override default settings I need to just put settings_local.py right next to settings.py.
- [Django]-How to add new languages into Django? My language "Uyghur" or "Uighur" is not supported in Django
- [Django]-Django – "Incorrect type. Expected pk value, received str" error
- [Django]-How to migrate back from initial migration in Django 1.7?
11đź‘Ť
I have two files. settings_base.py
which contains common/default settings, and which is checked into source control. Each deployment has a separate settings.py
, which executes from settings_base import *
at the beginning and then overrides as needed.
- [Django]-Django middleware difference between process_request and process_view
- [Django]-Import data from excel spreadsheet to django model
- [Django]-Django south migration – Adding FULLTEXT indexes
7đź‘Ť
The most simplistic way I found was:
1) use the default settings.py for local development and 2)
create a production-settings.py starting with:
import os
from settings import *
And then just override the settings that differ in production:
DEBUG = False
TEMPLATE_DEBUG = DEBUG
DATABASES = {
'default': {
....
}
}
- [Django]-Django limit_choices_to for multiple fields with "or" condition
- [Django]-Why is __init__ module in django project loaded twice
- [Django]-Default value for user ForeignKey with Django admin
2đź‘Ť
Somewhat related, for the issue of deploying Django itself with multiple databases, you may want to take a look at Djangostack. You can download a completely free installer that allows you to install Apache, Python, Django, etc. As part of the installation process we allow you to select which database you want to use (MySQL, SQLite, PostgreSQL). We use the installers extensively when automating deployments internally (they can be run in unattended mode).
- [Django]-How to delete project in django
- [Django]-ModuleNotFoundError: No module named 'grp' on windows
- [Django]-Why does django run everything twice?
1đź‘Ť
In addition to the multiple settings files mentioned by Jim, I also tend to place two settings into my settings.py file at the top BASE_DIR
and BASE_URL
set to the path of the code and the URL to the base of the site, all other settings are modified to append themselves to these.
BASE_DIR = "/home/sean/myapp/"
e.g. MEDIA_ROOT = "%smedia/" % BASEDIR
So when moving the project I only have to edit these settings and not search the whole file.
I would also recommend looking at fabric and Capistrano (Ruby tool, but it can be used to deploy Django applications) which facilitate automation of remote deployment.
- [Django]-Django.db.utils.IntegrityError: duplicate key value violates unique constraint "django_migrations_pkey"
- [Django]-Complete django DB reset
- [Django]-Django connection to postgres by docker-compose
1đź‘Ť
I have my settings.py file in an external directory. That way, it doesn’t get checked into source control, or over-written by a deploy. I put this in the settings.py file under my Django project, along with any default settings:
import sys
import os.path
def _load_settings(path):
print "Loading configuration from %s" % (path)
if os.path.exists(path):
settings = {}
# execfile can't modify globals directly, so we will load them manually
execfile(path, globals(), settings)
for setting in settings:
globals()[setting] = settings[setting]
_load_settings("/usr/local/conf/local_settings.py")
Note: This is very dangerous if you can’t trust local_settings.py.
- [Django]-Reload django object from database
- [Django]-Django Model() vs Model.objects.create()
- [Django]-Django in / not in query
1đź‘Ť
Well, I use this configuration:
At the end of settings.py:
#settings.py
try:
from locale_settings import *
except ImportError:
pass
And in locale_settings.py:
#locale_settings.py
class Settings(object):
def __init__(self):
import settings
self.settings = settings
def __getattr__(self, name):
return getattr(self.settings, name)
settings = Settings()
INSTALLED_APPS = settings.INSTALLED_APPS + (
'gunicorn',)
# Delete duplicate settings maybe not needed, but I prefer to do it.
del settings
del Settings
- [Django]-Django Queryset with year(date) = '2010'
- [Django]-How do I use django rest framework to send a file in response?
- [Django]-Django-reversion and related model
1đź‘Ť
So many complicated answers!
Every settings.py file comes with :
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
I use that directory to set the DEBUG variable like this (reaplace with the directoy where your dev code is):
DEBUG=False
if(BASE_DIR=="/path/to/my/dev/dir"):
DEBUG = True
Then, every time the settings.py file is moved, DEBUG will be False and it’s your production environment.
Every time you need different settings than the ones in your dev environment just use:
if(DEBUG):
#Debug setting
else:
#Release setting
- [Django]-Gunicorn Connection in Use: ('0.0.0.0', 5000)
- [Django]-Django queryset filter – Q() | VS __in
- [Django]-Django: remove a filter condition from a queryset
1đź‘Ť
Why make things so much complicated? I come into Django from a PHP/Laravel background. I use .env
and you can easily configure it.
Install this package
django-environ
Now, in the folder where you’ve settings.py
, create a file .env
(make sure to put this file in gitignore)
In the .env
file, put the env variables like debug setting state, secret key, mail credentials etc
A snapshot of example .env
SECRET_KEY="django-insecure-zy%)s5$=aql=#ox54lzfjyyx!&uv1-q0kp^54p(^251&_df75i"
DB_NAME=bugfree
DB_USER=postgres
DB_PASSWORD=koushik
DB_PORT=5433
DB_HOST=localhost
APP_DEBUG=True # everything is string here
In the settings, make sure to instantiate it using this
import environ
env = environ.Env()
environ.Env.read_env()
Now you can import values from the .env
file and put them wherever you want. Some examples in settings.py
SECRET_KEY = env('SECRET_KEY')
DEBUG = bool(env('APP_DEBUG', False))
You can also put default value too like this
env('DB_NAME', 'default value here')
TIP
You can create another .env.example
in the same folder where you’ve .env
file and you can have a template of .env
and you can commit the .example
file. It helps the future dev to know easily what env variables are there.
.env.example
would be something like this
SECRET_KEY=VALUE_HERE
DB_NAME=VALUE_HERE
DB_USER=VALUE_HERE
DB_PASSWORD=VALUE_HERE
DB_PORT=VALUE_HERE
DB_HOST=VALUE_HERE
EMAIL_HOST=VALUE_HERE
EMAIL_PORT=VALUE_HERE
EMAIL_HOST_USER=VALUE_HERE
EMAIL_HOST_PASSWORD=VALUE_HERE
DEFAULT_FROM_EMAIL=VALUE_HERE
- [Django]-How do I get the object if it exists, or None if it does not exist in Django?
- [Django]-What is the SQL ''LIKE" equivalent on Django ORM queries?
- [Django]-Get last record in a queryset
0đź‘Ť
I think it depends on the size of the site as to whether you need to step up from using SQLite, I’ve successfully used SQLite on several smaller live sites and it runs great.
- [Django]-Data Mining in a Django/Postgres application
- [Django]-Get Timezone from City in Python/Django
- [Django]-AngularJS with Django – Conflicting template tags
0đź‘Ť
I use environment:
if os.environ.get('WEB_MODE', None) == 'production' :
from settings_production import *
else :
from settings_dev import *
I believe this is a much better approach, because eventually you need special settings for your test environment, and you can easily add it to this condition.
- [Django]-ValueError: The field admin.LogEntry.user was declared with a lazy reference
- [Django]-Allowing only super user login
- [Django]-How do I clone a Django model instance object and save it to the database?
0đź‘Ť
This is an older post but I think if I add this useful library
it will simplify things.
Quickstart
pip install django-configurations
Then subclass the included configurations.Configuration class in your project’s settings.py or any other module you’re using to store the settings constants, e.g.:
# mysite/settings.py
from configurations import Configuration
class Dev(Configuration):
DEBUG = True
Set the DJANGO_CONFIGURATION
environment variable to the name of the class you just created, e.g. in ~/.bashrc
:
export DJANGO_CONFIGURATION=Dev
and the DJANGO_SETTINGS_MODULE
environment variable to the module import path as usual, e.g. in bash:
export DJANGO_SETTINGS_MODULE=mysite.settings
Alternatively supply the --configuration
option when using Django management commands along the lines of Django’s default --settings
command line option, e.g.:
python manage.py runserver --settings=mysite.settings --configuration=Dev
To enable Django to use your configuration you now have to modify your manage.py or wsgi.py script to use django-configurations’ versions of the appropriate starter functions, e.g. a typical manage.py using django-configurations would look like this:
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
os.environ.setdefault('DJANGO_CONFIGURATION', 'Dev')
from configurations.management import execute_from_command_line
execute_from_command_line(sys.argv)
Notice in line 10 we don’t use the common tool django.core.management.execute_from_command_line
but instead configurations.management.execute_from_command_line
.
The same applies to your wsgi.py file, e.g.:
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
os.environ.setdefault('DJANGO_CONFIGURATION', 'Dev')
from configurations.wsgi import get_wsgi_application
application = get_wsgi_application()
Here we don’t use the default django.core.wsgi.get_wsgi_application
function but instead configurations.wsgi.get_wsgi_application
.
That’s it! You can now use your project with manage.py and your favorite WSGI enabled server.
- [Django]-What is the Simplest Possible Payment Gateway to Implement? (using Django)
- [Django]-Chained method calls indentation style in Python
- [Django]-Django related_name for field clashes
-2đź‘Ť
In fact you should probably consider having the same (or almost the same) configs for your development and production environment. Otherwise, situations like “Hey, it works on my machine” will happen from time to time.
So in order to automate your deployment and eliminate those WOMM issues, just use Docker.
- [Django]-Nginx doesn't serve static
- [Django]-Bypass confirmation prompt for pip uninstall
- [Django]-Remove pk field from django serialized objects