Skip to main content

Command Palette

Search for a command to run...

Simple Django Tip #1

Multiple settings file, one for each environment

Updated
β€’4 min read
Simple Django Tip #1
S

I'm an entrepreneur and full-stack developer who brings ideas to life through SaaS products, internal tools, and automation. I work across FlutterFlow, Supabase, and modern no-code platforms.

What sets me apart is understanding the full pictureβ€”not just technical execution, but customer success, marketing, sales, and partnerships. Entrepreneurship taught me what no classroom could.

I also built My AI Digest (myaidigest.news), a personalized newsletter cutting through AI noise to deliver actionable insights tailored to your goals.

I'm a proud generalist.

This is a super short post with a simple tip that can be performed in any Django project. Though simple, it aids in keeping the code clean, and easy to debug and maintain. I cannot emphasize the usefulness of this step.

When I started to learn Django in the past, I used to follow Django's documentation and build my projects. This is how I used to create a project,

django-admin startproject <my_fancy_project>

On becoming a seasoned user, I started to use pydanny's cookiecutter. This had pros and cons, initially, I was blinded by the cons. Irrespective of whether I need all the properties that come with the cookiecutter, I used to have them religiously, install required packages or comment them out.

Since I do this activity only when I start a project, it doesn't seem like a lot of work. Outside of work, when there was a need to create small projects that accompany my blog post or to try a new feature, I started to feel that cookiecutter was overkill. It was meant for production-grade work, not for random pieces of work.

At the same time, the vanilla django project was also insufficient as I'd deploy the project with some cloud provider. Especially, with one settings.py and dumping all properties related to all environments was not the right way of doing things.

I now follow this approach of having multiple settings.py and using the right one depending on the environment where I run the project. I wanted to share the steps in this short post so that you also follow these steps whenever you start a Django project and make it a default 😎

Step 1: Let's start by creating a virtual environment

Navigate to the folder where you intend to create a Django project. Execute the command below that creates a virtual environment πŸ‘‡

py -m venv <name of your virtual environment>
πŸ’‘
This command is for a Windows machine. Check this article for a primer on Python virtual environments.

Step 2: Install Django

pip install Django

Step 3: Create a Django project

django-admin startproject <your-fancy-project-name-here>

Here is how the folder structure will look like on executing the command

Step 4: Start the development server

On changing the directory to the newly created project, start the development server using the command below πŸ‘‡

python manage.py runserver

This is what the terminal looks like. If you notice, it makes use of myfancyproject.settings for the properties that it needs.

Step 5: Let's create multiple settings file

Let's stop the server for the moment. Next, create a folder called settings at the project's root level. Move settings.py under settings folder. Rename settings.py to base.py. Create two additional files in the same folder namely local.py and production.py.

As you might have guessed base.py serves as the common file for all environments. local.py will override properties that pertain to a development environment. production.py will maintain properties that will be required in a production environment.

πŸ’‘
You can have a staging.py too, that you can use in your staging environment

Step 6: Extend base.py in the other two files

Open local.py and production.py and add the line of code shown below πŸ‘‡

from .base import *

This means all properties from base.py are accessible in the other two files. We now need to modify properties that are particular to each environment.

The first property we may change is DEBUG = False in production.py as we may not want to show the end user any sensitive information in case of errors.

Likewise, we may want to have different email IDs in each of the environments. There are so many other properties that vary from environment to environment.

Step 7: Modify manage.py to pick up the right file

Now that we have separate files, we need to instruct manage.py to pick up the right file. With the current setup, the development server will not start as there is no file with the namesettings.py. Below is how manage.py looks like by default πŸ‘‡

We now need to change the logic in Line No. 9. Here's how we do πŸ‘‡

def main():
    """Run administrative tasks."""
    if base.DEBUG:
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myfancyproject.settings.local")
    else:
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myfancyproject.settings.production")

Based on whether the property DEBUG is True or False, we navigate to the appropriate file. This is one common way of branching out but not the only way to do so.

We can have an environment variable that denotes the environment we are currently in, and we can branch out based on that. These are dependent on your project and scenario.

Step 8: Start the development server again

When we start the development server now, we should be able to see that it picks up local.py like so πŸ‘‡

That is all for now! Quite simple, but it helps to keep the code well organized.

T
thon1y ago

Hello, I’m a newbie trying to learn Django, I followed the exact same steps as described here, and had an error on the 7th step. the name 'base' is not defined, I think you forgot to include this line in 'manage.py' on line 5 : "from project_name.settings import base"

1
S

Let me check thon. Thanks for pointing that out.

M

Thank you for this clever idea, Sambhavi! It should help keep my code cleaner, safer, and more consistent from project to project, as well as being a time saver.

1
S

Thanks for reading the post Mike. All credits to pydanny's cookiecutter ⭐

Over the years I have learned to take what's required than consuming in a wholesome manner. This is one of those. And I should say it makes a lot of difference when we take things in parts, saves a lot of unnecessary headache.

1