How to Manage Local VS Production Settings in Django

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
Sample Image

and I had updated my manage.py like these
Sample Image

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.

  1. 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.

  2. 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.

  3. 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 the 500 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:

  1. Your settings will be modular based on each environment

  2. You may import the master_settings.py containing the base configuration in the environmnet_configuration.py and override the values that you want to change in that environment.

  3. 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



Leave a reply



Submit