Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make some Django settings accessible by staff?

In Django, settings are stored in a file, settings.py. This file is part of the code, and goes into the repository. It is only the developers who deal with this file. The admin deals with the models, the data in the database. This is the data that the non-development staff edits, and the site visitors see rendered in templates.

The thing is, our site, and many others, have lots of settings options that should be edited by non-developer staff. We're talking about stand-alone site-wide constants that really have no place in the database. Putting them in the database will result in numerous pointless queries. Caching could alleviate that, but that seems unnecessarily complex to handle what can be done with a single line in the settings.py file.

I did notice this dbsettings app, but it is old and unmaintained. I also noticed that the django e-commerce app, Satchmo, includes a use-case specific fork of this dbsettings app. We could build something similar into our site, an app that stores some settings as key/value pairs in a single database table, but it just really seems like the wrong approach. Why put something in the DB that doesn't belong there just to make it more easily editable by non-developers?

We have a list of site-wide settings on our Django site that we want to be editable by non-developer administrators. What is the best way of going about this?

like image 470
Apreche Avatar asked Dec 02 '09 15:12

Apreche


3 Answers

Something like dbsettings (as you mentioned) seems like the way to go. From the reasons for existence for that project:

Not all settings belong in settings.py, as it has some particular limitations:

  • Settings are project-wide. This not only requires apps to clutter up settings.py, but also increases the chances of naming conflicts.

  • Settings are constant throughout an instance of Django. They cannot be changed without restarting the application.

  • Settings require a programmer in order to be changed. This is true even if the setting has no functional impact on anything else.

If dbsettings doesn't work for you, then implement your own, or fork it. It doesn't seem like it'd be too arduous.

like image 162
Dominic Rodger Avatar answered Nov 01 '22 23:11

Dominic Rodger


I'm actually a big fan of dbsettings, and keep meaning to publish my fork that patches it to work with Django 1.1 (not actually a big change). Looks like someone has updated it already.

However, you're probably right that this is overkill for what you need. One thing I've done before is to add a line to the end of settings.py that imports and parses a YAML file. YAML is a simple markup language, which at its most basic is just KEY: VALUE ...

CONSTANT1: MyValue
CONSTANT2: Anothervalue

If you put this somewhere editors can access it, then at the end of settings.py you just do:

import yaml
try:
    globals().update(yaml.load(open('/path/to/my/yaml/file.yml')))
except:
    pass

You'll need the Python YAML library to parse the YML file.

The downside to this approach is that you'll need to restart Apache to get it to pick up the changes.

Edited to add It wouldn't be particularly difficult to build a front end which could edit this file, and provide a button which runs a script to restart Apache.

like image 40
Daniel Roseman Avatar answered Nov 02 '22 00:11

Daniel Roseman


If you must avoid server restarts then a logical place for the settings is the database as Dominic and Daniel said, but you'll need to invalidate cached settings object every time it is updated.

Looks like it's possible to re-set values in the cache with Django's low level cache API. All you want should be achievable with these calls:

 cache.set('settings', local_settings)
 cache.add('settings', local_settings)
 local_settings = cache.get('settings')
 cache.delete('settings')
like image 45
Evgeny Avatar answered Nov 01 '22 23:11

Evgeny