Tutorials  Articles  Notifications  Login  Signup


RK

Rajan Kumar

Founder at HackersFriend Aug. 12, 2020, 1:17 p.m. ⋅ 2034 views

How to separate Django application config files from code using python decouple


We have to put a lot server specific details in settings.py file of any django application, like DB username and password, s3 password, email server details etcetera.

These details are written in the code file, hence whenever we deploy our application or put on git, they get exposed. Ideally they shouldn't be stored or hardcoded anywhere in code. secret_key of you django application shouldn't be exposed either. This also becomes a mess when we have multiple environments of application. We will have to manually hard code values of server details of each environment. 

Some developers overcome this issue by keeping multiple settings.py file. like - dev_settings.py, test_settings.py, prod_settings.py.

In this article, I'll show you how can you use Python decouple to separate out your server specific details from application code. So you no longer have to keep multiple settings.py file or manually edit everytime you deploy to a different environment.

Installation

$ pip install python-decouple

 Implementation

1. Create a .env file in your root directory and put all details in it. (You can create .ini file, if you don't want to create .env file). You can learn more from official documentation from here

SECRET_KEY=1&*h)h*^)#4hjkhsad^45**^0110_!77
DEBUG=True
DB_NAME=MY_DB
DB_USER=TEST_USER
DB_PASSWORD=1h1!7(*0^5ggdap
DB_HOST=127.0.0.1

 Once after you create this file. Do add this into your .gitignore also, so that this doesn't get included when you check in your code. 

2. Now you can update your settings.py file.

In order to use your variables, you need to import it first in your settings.py file.

from decouple import config

 Now update details in your settings.py file, like this:

SECRET_KEY = config('SECRET_KEY')
DEBUG = config('DEBUG', cast=bool)
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': config('DB_NAME'),
        'USER': config('DB_USER'),
        'PASSWORD': config('DB_PASSWORD'),
        'HOST': config('DB_HOST'),
        'PORT': '',
    }
}

Important thing to note here is, you need to cast variable data types as per the type django expects. You can specify the cast argument, and provide the cast argument with whatever data type you want to cast into. 

DEBUG = config('DEBUG', cast=bool)
EMAIL_PORT = config('EMAIL_PORT', cast=int)

You can also pass any callable in cast. 
Suppose you have a value separated by comma in your .env file, like this:

ALLOWED_HOSTS=.localhost, .mywebsite.com

You can pass it into settings.py file like this:

ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=lambda x: [s.strip() for s in x.split(',')])

Python decouple comes with a method called Csv() to make this work simple for you.

from decouple import config, Csv

ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=Csv())

 

Default Values

You can also specify a default value in config() this will be used, when no value is provided in .env file.

DEBUG = config('DEBUG', default=True, cast=bool)

 



HackerFriend Logo

Join the community of 1 Lakh+ Developers

Create a free account and get access to tutorials, jobs, hackathons, developer events and neatly written articles.


Create a free account