How to manage local vs production settings in Django?
In settings.py
:
try:
from local_settings import *
except ImportError as e:
pass
You can override what needed in local_settings.py
; it should stay out of your version control then. But since you mention copying I'm guessing you use none ;)
Django: How to manage development and production settings?
The DJANGO_SETTINGS_MODULE
environment variable controls which settings file Django will load.
You therefore create separate configuration files for your respective environments (note that they can of course both import *
from a separate, "shared settings" file), and use DJANGO_SETTINGS_MODULE
to control which one to use.
Here's how:
As noted in the Django documentation:
The value of DJANGO_SETTINGS_MODULE should be in Python path syntax, e.g. mysite.settings. Note that the settings module should be on the Python import search path.
So, let's assume you created myapp/production_settings.py
and myapp/test_settings.py
in your source repository.
In that case, you'd respectively set DJANGO_SETTINGS_MODULE=myapp.production_settings
to use the former and DJANGO_SETTINGS_MODULE=myapp.test_settings
to use the latter.
From here on out, the problem boils down to setting the DJANGO_SETTINGS_MODULE
environment variable.
Setting DJANGO_SETTINGS_MODULE
using a script or a shell
You can then use a bootstrap script or a process manager to load the correct settings (by setting the environment), or just run it from your shell before starting Django: export DJANGO_SETTINGS_MODULE=myapp.production_settings
.
Note that you can run this export at any time from a shell — it does not need to live in your .bashrc
or anything.
Setting DJANGO_SETTINGS_MODULE
using a Process Manager
If you're not fond of writing a bootstrap script that sets the environment (and there are very good reasons to feel that way!), I would recommend using a process manager:
- Supervisor lets you pass environment variables to managed processes using a program's
environment
configuration key. - Honcho (a pure-Python equivalent of Ruby's Foreman) lets you define environment variables in an "environment" (
.env
) file.
Finally, note that you can take advantage of the PYTHONPATH
variable to store the settings in a completely different location (e.g. on a production server, storing them in /etc/
). This allows for separating configuration from application files. You may or may not want that, it depends on how your app is structured.
Init.py goes for local settings.py rather than production settings.py DJANGO
Update an env keys
Try putting a key like environment in env file as
ENVIRONMENT = TEST
And use manage.py to select the suitable settings for production or local settings.
Use if case. I have done this in my real life deployable project, and it works in both production and local environment.
I have these files in my settings folder
and I had updated my manage.py like these
Here dep is the environment key which says whether the server is in development or deployment.
Conclusion
Add a key for the current environment and select the settings wisely.
Django project settings for production and development
When I did git pull, __init__.py
inside the settings was also changed. I did not know about it. The developer who I know advised me to check this file. I discovered that different setting file was set as default. I corrected it. Now it is working.
What is the recommended method for deploying Django settings to a production environment?
There is not one recommended way of deploying a Django app. The official documentation provides a guide for deploying with Apache and mod_wsgi. Some other options are a PaaS like Heroku/Dokku or deployment with Docker
It's common to divide your settings in different files. You could for example divide settings in four different files:
- base file (base.py) - Common settings for all environments (every file below imports from this with
from .base import *
- development file (development.py) - settings specific for development, (DEBUG = True etc...)
- production file (production.py) - settings specific for the production environment. (DEBUG = False, whitenoise configuration etc)
- testing file (testing.py)
You can control what settings file is loaded with the environment variable DJANGO_SETTINGS_MODULE
It is also common recommended practice that you store secrets like the SECRET_KEY in environment variables. SECRET_KEY = os.environ.get('SECRET_KEY', None)
. Or check out the django-environ package.
Check out this repo for an example setup.
How to properly manage django production and development files
hope you are well.
To answer the following questions I will do so based in the format you have asked.
You ask about management of production and development files with source control (namely GitHub). It would be best to store these in different branches of source control. Example: "main" branch being used for production and a "development" branch being used for development. This will allow you to work with both branches and you can merge development branch into the production branch.
The best way you can manage sensitive information such as passwords and keys in source control is to avail of
.env
files (What is the use of python-dotenv?), which stores variables in an environment. You can store variables in this file and tell GitHub to ignore this file in the.gitignore
file.You mention ideal file structure. There are many ways which files can be structured and normally I would say this is preference on the developers behalf as this doesn't really matter as long as the developer and future developers can make sense of the file structure. From personal recommendation and this is my own opinion.
Project setup
- staticfiles folder
- projectName
- settings.py etc
- app
- app files
- manage.py
Hope this can be of some benefit to you and some clarity around your questions.
Have a good day.
How does Heroku Django picks up settings file during production? Multiple settings
Yes the answer you came up with is logically correct but might not work.
Change your wsgi.py
to set DJANGO_SETTINGS_MODULE; looking at where it is being run on: (You will have to set environment variable ENV=Heroku in heroku for this)
import os
from django.core.wsgi import get_wsgi_application
if os.getenv("ENV") == "Heroku":
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'my_app.production_settings')
else:
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'my_app.dev_settings')
application = get_wsgi_application()
You can also change your manage.py
to have the same incase you want to use manage.py runserver
for development ease:
import os
import sys
def main():
"""Run administrative tasks."""
if os.getenv("ENV") == "Heroku":
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'my_app.production_settings')
else:
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'my_app.dev_settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()
Q: Why this approach instead of your solution to directly set the env variable in heroku?
A: I haven't tested it, but on each restart wsgi.py
runs os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'my_app.settings')
overwriting the DJANGO_SETTINGS_MODULE
environment variable manually set by you in heroku. So, you will have to set it in wsgi.py.
Best way to handle different configuration/settings based on environment in Django project
As an answer to the question:
Is DEBUG == False supposed to mean that the app is running in production environment?
DEBUG
is a configuration that you define in your setting.py
file.
If set to
True
, in case of un-handled exception it displays the complete stack-trace along with the values of all the declared variables.If set to
False
, your server just returns the500
status code without any stack-trace.
In production, you must have DEBUG
set to False
in order to prevent potential risk of security breach, and other information which you wouldn't want your user to know.
In order to use different settings
configuration on different environment, create different settings file. And in your deployment script, start the server using --settings=<my-settings.py>
parameter, via which you can use different settings on different environment.
Benefits of using this approach:
Your settings will be modular based on each environment
You may import the
master_settings.py
containing the base configuration in theenvironmnet_configuration.py
and override the values that you want to change in that environment.If you have huge team, each developer may have their own
local_settings.py
which they can add to the code repository without any risk of modifying the server configuration. You can add these local settings to.gitnore
if you use git or.hginore
if you Mercurial for Code Version Control. That way local settings won't even be the part of actual code base keeping it clean.
Related Topics
Pandas Groupby: How to Get a Union of Strings
Python Garbage Collector Documentation
How to Capture Stdout Output from a Python Function Call
How to Make Ipython Notebook Matplotlib Plot Inline
Getting the Class Name of an Instance
Create a Directly-Executable Cross-Platform Gui App Using Python
How to Implement an Efficient Bidirectional Hash Table
Checking Whether a String Starts with Xxxx
Django. Override Save for Model
What Is the Intended Use of the Optional "Else" Clause of the "Try" Statement in Python
Apply VS Transform on a Group Object
Using Pip Behind a Proxy with Cntlm
How to Escape Os.System() Calls
Django Urls Typeerror: View Must Be a Callable or a List/Tuple in the Case of Include()