Django – Local Settings Revisited

Settings in a Django project will differ between development and production instances. In my case, I develop my projects on my laptop running the built in Django webserver and the sqlite3 database, while the production systems use Apache and MySQL (on another server). Media paths, the DEBUG setting, and other attributes can differ.

After browsing around several web sources, I learned that the prevailing wisdom is to include an import of a local-settings.py file that in turn imports another settings file that contains the installation specific values. All of the settings files are included in version control, except local-settings.py, which is different for each installation. This setup has worked fine with my personal applications as well.

However, I learned this week that the way my central IT office allows access to servers that makes this method unworkable. I have been given easy access to the development server, where I have been able to create and modify the local-settings.py file as needed. What I was told this week is that I will have no access to the quality assurance or production servers, except through a deploy mechanism that copies the entire application directory from the dev server to QA, and from QA to production. This means that I can’t create a unique local-settings.py on each box.

Instead, I need to be able to determine the instance based on values available at run time. My server admin told me of an Apache environment variable called ‘tier’ that he maintains in the Apache configuration, but despite my efforts to find a way to access the variable, I was unsuccessful, If anyone out there can guide me in the right direction, please leave a comment.

One down side to using the Apache variable is that not all of my installations use that web server, so I’d still have to find an alternative (or use a default value) to properly identify other systems.

My next idea was to read the name of the server running the application, and using that to make the decision. The getfqdh() function of Python’s socket module returns the fully qualified domain name, which worked well to identify the instance. Here’s the code (your domain names may vary):

settings.py

## Determine the server environment.

import socket

fqdn = socket.getfqdn() ## Get the fully qualified domain name

SERVER_ENVIRONMENT = 'UNKNOWN'

if fqdn == 'dashdrum_laptop':          ## laptop
    SERVER_ENVIRONMENT = 'Laptop'
elif fqdn == 'dev.example.com':       ## dev server
    SERVER_ENVIRONMENT = 'DEV'
elif fqdn == 'qa.example.com':         ## qa server
    SERVER_ENVIRONMENT = 'QA'
elif fqdn == 'example.com':            ## production server
    SERVER_ENVIRONMENT = 'PROD'

A potential problem with this method is that the server name may change over time. More on this here.

Once I know the environment, I can import the proper settings file thusly:

settings.py

## Get server specific settings

try:
    if SERVER_ENVIRONMENT == 'Laptop':
        from laptop_settings import *
    elif SERVER_ENVIRONMENT == 'DEV':
        from dev_settings import *
    elif SERVER_ENVIRONMENT == 'QA':
        from qa_settings import *
    elif SERVER_ENVIRONMENT == 'PROD':
        from prod_settings import *
except ImportError:
    pass

Assuming that I have the correct domain names and the correct settings for each instance, I should be good to go in each environment.

Comments are closed.