DEV Community

Cover image for How to split Django settings for different environments?

How to split Django settings for different environments?

Valentine Solonechnyi
Full-stack web developer from Ukraine
・3 min read

So it's time to put your code into production. That means you have to connect some third party stuff, probably some external database or SMTP server. At the same time it would be nice to keep an option to modify and test your codebase with your local database and double-check on some other staging or QA server. But how to achieve this with default file?

Searching for the solution I found several approaches of splitting the Django settings, but one that worked for me appeared to be a mixture. Here's how I've got it to work with AWS EC2, but it should work with any python environment where you can set your own env variables.

Short recipe

  1. Django settings as a module.
  2. Key environmental variables for production and/or staging servers.

Directory view

Enter fullscreen mode Exit fullscreen mode

Step-by-step guide

1. Set environmental variable with unique key or use one.

I didn't set any env vars during development. But once I deployed my app to the staging server, it got a new env variable called 'RDS_DB_NAME'. I used it to differentiate between my local server and staging/production, but you can use your own unique key to perform the main check in the file (i.e.'ENV_NAME' : 'Staging').

2. Prepare

from pathlib import Path
import os

# The most important thing is to be build relative path
BASE_DIR = Path(__file__).resolve().parent.parent.parent


#...other environmentally independent settings 
Enter fullscreen mode Exit fullscreen mode

3. Add environment-specific settings

Since we have, we can put the rest of the settings into their respective files:,, (you've got the idea).

By the way, don't forget to place your sensitive data (secrets, api keys etc.) into env variables instead of hard-coding them into your Here's the example of retrieving them in your settings:

'SECRET': os.environ.get('SECRET_KEY')

4. Tweak the import in with if statement

Having all the settings in a separate module allows us not to specify local config directly each time we run runserver, because Django loads by default. And our settings module/folder is simply an equivalent to it.

Here's the from the settings folder.

from .base import *
import os

if os.environ.get("ENV_NAME") == 'Production':
    from .production import *
elif os.environ.get("ENV_NAME") == 'Staging':
    from .staging import *
    from .local import *
Enter fullscreen mode Exit fullscreen mode

Now, whenever your Django app is initialized on the server, your environment variable called "ENV_NAME" will determine the proper settings file. And if it's just your local dev server, no env variables will be accessible and your app will fall back to settings.

*If you happened to use AWS Beanstalk for deploying python app, you might want to simplify your to something shorter:

from .base import *
import os

if os.environ.get("RDS_DB_NAME") is None:
    from .local import *
Enter fullscreen mode Exit fullscreen mode

In this case, we're only telling the server to check one env variable and fallback to What about the production configuration then? Well, Beanstalk allows you to specify preferred settings in an environmental variable called DJANGO_SETTINGS_MODULE. Thus, you can just tune your Beanstalk app to load respective configuration like this:

DJANGO_SETTINGS_MODULE: "your_main_django_app.settings.production"

And that's all.

Everyone gets its own settings and your runserver works as before. Happy production.

This article was originally published in my blog post.

Discussion (0)