Correct way to handle default model fields.

With Kong, I have been trying to figure out a way to provide overridden model defaults. At work, our pythonpath's default to /home/code, however your setup is probably different. It would be useful if there was a simple way to let you override the defaults for your Kong installation.

pythonpath = models.CharField(max_length=255, default="/home/code")

I received a pull request that put a KONG_PYTHONPATH_DEFAULT setting, which would be read in as the default. However, it seems like this doesn't scale particularly well, and would be annoying if you have 5-10 fields to make defaults for.

So I thought up a couple of different approaches to this problem, and am curious if people have input, or a better way to solve this.

One Big Setting

This would allow for a setting, but it would only be one setting for all of the kong defaults. I'm thinking about a dict, where the key is the model_field name, or just the field name. The key would obviously be the default (or a callable that returns the default).

KONG_DEFAULTS = {
    'servername': 'ljworld.com',
    'pythonpath': '/home/code',
}

This would keep things in the settings, but not cause a huge amount of settings bloat.

Specify a place to hold your defaults

Specify a setting along the lines of KONG_DEFAULT_PATH, which would be a module on the pythonpath. I would import this module and then try and pull the name of defaults from there. I would provide a sane default in Kong for this, that would be an example of how to do it.


KONG_DEFAULT_PATH = 'kong.defaults'

#kong/defaults.py
pythonpath = '/home/code'
servername = 'ljworld.com'

So you could set KONG_DEFALUT_PATH, and then redefine the values there. This is basically defining a convention for setting the default values on a model.

However, this is basically the same problem/solution as some kind of application specific settings. I really think this would be valuable, allowing reusable apps to specify default settings, and then letting users override them

Storing it in the database

I could create a super simple model that would hold defaults for my fields. This would allow the user to set the defaults in the database, and then I could pass a callable to the default, which would check for the existence of the model in the DB. This doesn't seem like a very good option, but would at least allow for configurable changes without touching the code.

I'm probably DOIN' IT WRONG

It seems like a subset of a larger problem, which is that it isn't easy to define application specific information. That is an ongoing Django problem, without a good solution. I am imagining a third party application that might make this process easier. Does anyone have a good solution to this?




Comments

1 SafPlusPlus says...

I'd probably go with something like using getattr.

from django.conf import settings

KONG_DEFAULT_PATH = settings.getattr('KONG_DEFAULT_PATH', '/home/code')

...

pythonpath = models.CharField(max_length=255, default=KONG_DEFAULT_PATH)

This way the user doesn't have to define the setting, but can overwrite it if he (or she) needs to.

Posted at 7:06 a.m. on November 24, 2009

2 SafPlusPlus says...

My bad... That should be:

KONG_DEFAULT_PATH = getattr(settings, 'KONG_DEFAULT_PATH', '/home/code')

Posted at 7:10 a.m. on November 24, 2009

3 Honza Kral says...

we do something like: http://gist.github.com/241788

Posted at 10:51 a.m. on November 24, 2009

4 Chris Moffitt says...

Check out Bruce's livesettings module. We use it in Satchmo and it's a pretty good solution to the problem: http://bitbucket.org/bkroeze/django-livesettings/overview/

Posted at 1:21 p.m. on November 24, 2009

5 Zellyn Hunter says...

This is slightly magical, but I wrote a tiny function so I could define settings in app_settings.py, but let settings.py override them, without the getattr clutter: http://gist.github.com/241869

Posted at 1:45 p.m. on November 24, 2009

6 Harro says...

I actually wrote a couple of apps where even the relations between the apps came from the settings.

Then I created my initial migration and saw the big hole in my idea ;-)

Right now I do have a limit_choices_to which limits the foreign key user selection.

Posted at 8:09 a.m. on November 25, 2009

7 Richard Henry says...

Why not use Virtualenv? No more worrying about the Python path, or even the version of Python for that matter -- the right version of Python and all of the requirements are distributed with the source code.

Posted at 9:19 p.m. on November 26, 2009

8 Catherine says...

Very nice article. I thought to let you know thta you website isn't getting displayed properly on opera mini web browser on my mobile phone.

Have a good time...sorry for typos

Posted at 11:46 p.m. on November 30, 2009

Comments support markdown

Comments are closed.

Comments have been close for this post.