Default settings in Django

A problem with Django is that you can't have default settings unless you're a core Django developer.

This would be nice to have per-app or even per-funky-module, so I decided I'd implement something to support it!

Here's how I did it: create a base class, with a metaclass. When this base class is subclassed, take the attributes and loop through them. If the attribute is all uppercase and isn't set in the main configuration (yet), copy it there.

This ended up looking like:
class GlobalDefaultSettingsBase(type):
    def __new__(cls, name, bases, attrs):
        from django.conf import settings
        new = super(GlobalDefaultSettingsBase, cls).__new__
        new_cls = new(cls, name, bases, attrs)
        if name == "GlobalDefaultSettings":
            return new_cls
        for (attr, value) in attrs.iteritems():
            if attr == attr.upper() and not hasattr(settings, attr):
                print "SETTING", attr, "TO", repr(value)
                print settings
                print settings._target
                setattr(settings, attr, value)
        return new_cls

class GlobalDefaultSettings(object):
    """A base class for adding default global settings to the Django settings
    object.

    All attributes which are in the upper case will be merged into the existing
    configuration, unless they're already set.

    This is a simple solution for having default settings without `getattr`.
    All you have to insure is that your subclass is constructed before the
    access of the defaults you provide -- which should be fairly easy.
    """
    __metaclass__ = GlobalDefaultSettingsBase

To use it, simply make a subclass and set some settings!

class MyDefaults(DefaultSettings):
MY_SETTING_A = "Hello world!"
MY_SETTING_B = ["Hey guys"]

And that's all you need. If either of the settings is set in the project's settings.py, that setting will effectively take precedence!

Obviously, there's no great place to put this code since it really belongs to core Django.

In fact, Django should itself be using this style - as it is now, all default settings are specified in one huge file without any good correlation.


Comments

Comment the entry:

Name: (required, possibly pseudonym)
Remember me (cookie)

E-mail: (not required, never published, solely for me to reply to you in person)

URL:

Comment:

RSS 2.0