Mathieu Dhondt
Mathieu Dhondt

Reputation: 8914

Separate custom settings variable between development, staging and production

I'm following the project structure as laid out by Zachary Voase, but I'm struggling with one specific issue.

I'd very much like to have a custom settings boolean variable (let's call it SEND_LIVE_MAIL) that I would be using in the project. Basically, I'd like to use this settings variable in my code and if SEND_LIVE_MAIL is True actually send out a mail, whereas when it is set to False just print its contents out to the console. The latter would apply to the dev environment and when running unittests.

What would be a good way of implementing this? Currently, depending on the environment, the django server uses dev, staging or prd settings, but for custom settings variables I believe these need to be imported 'literally'. In other words, I'd be using in my views something like

from settings.development import SEND_LIVE_MAIL

which of course isn't what I want. I'd like to be able to do something like:

from settings import SEND_LIVE_MAIL

and depending on the environment, the correct value is assigned to the SEND_LIVE_MAIL variable.

Thanks in advance!

Upvotes: 2

Views: 816

Answers (4)

patrys
patrys

Reputation: 2769

import os
PROJECT_PATH = os.path.dirname(__file__)
try:
    execfile(os.path.join(PROJECT_PATH, local_settings.py'))
except IOError:
    pass

Then you can have your local_settings.py behave as if it was pasted directly into your settings.py:

$ cat local_settings.py
INSTALLED_APPS += ['foo']

Upvotes: 2

Andrew Ingram
Andrew Ingram

Reputation: 5220

The simplest solution is to have this at the bottom of your settings file:

try:
    from local_settings import *
except ImportError:
    pass

And in local_settings.py specify all your environment-specific overrides. I generally don't commit this file to version control.

There are more advanced ways of doing it, where you end up with a default settings file and a per-environment override.

This article by David Cramer covers the various approaches, including both of the ones I've mentioned: http://justcramer.com/2011/01/13/settings-in-django/

Upvotes: 3

mVChr
mVChr

Reputation: 50185

You can do something like this for a wide variety of environment based settings, but here's an example for just SEND_LIVE_MAIL.

settings_config.py

import re
import socket

class Config:
    def __init__(self):
        fqdn = socket.getfqdn()
        env = re.search(r'(devhost|stagehost|prodhost)', fqdn)
        env = env and env.group(1)
        env = env or 'devhost'
        if env == 'devhost':
            self.SEND_LIVE_MAIL = # whatever
        elif env == 'stagehost':
            self.SEND_LIVE_MAIL = # whatever
        elif env == 'prodhost':
            self.SEND_LIVE_MAIL = # whatever

config = Config()

settings.py

from settings_config import config

SEND_LIVE_MAIL = config.SEND_LIVE_MAIL

Upvotes: 1

Chris Pratt
Chris Pratt

Reputation: 239320

You shouldn't be importing directly from your settings files anyways. Use:

>>> from django.conf import settings
>>> settings.SEND_LIVE_MAIL
True

Upvotes: 6

Related Questions