开发者

Django: Allow admin user to edit site-wide settings?

I have a Django site, and I'd like to allow a couple of site-wide settings:

ADMIN_EMAIL - email address for an administrative user
REMINDER_TEXT - email text for an email that t开发者_开发问答he site will generate once a week

to be edited in the admin interface.

What is the most sensible way to do this? Should I store these values in settings.py, or somewhere in the database?

This previous SO question seems to be related, but I don't think it's ever been fully answered.

Thanks!


I've tried dbsettings (as well as the newer fork of it on github), and they are useful - but a bit too heavy-weight for my needs. Instead, I implemented a simpler method. I did it using a JSONField (from Postgres 9.3) - but you might prefer to use a TextField (use max_length=1000 or somesuch) as it's simpler to explain to people how to enter a string instead of JSON:

1) First, build your own Settings Model (maybe in core/models.py):

class Setting(models.Model):
    """
    Model for site-wide settings.
    """
    name = models.CharField(max_length=200, help_text="Name of site-wide variable")
    value = JSONField(null=True, blank=True, help_text="Value of site-wide variable that scripts can reference - must be valid JSON")

    def __unicode__(self):
        return self.name

2) Then, add an admin interface (in core/admin.py):

class SettingAdmin(admin.ModelAdmin):
    list_display = ['name', 'value']

admin.site.register(Setting, SettingAdmin)

3) Build and run your migrations:

python manage.py schemamigration core --auto
python manage.py migrate core

4) Add to the top of base.html:

<script type="text/javascript">
    //Auto-exported site-wide settings
    {% autoescape off %}var site_settings = {{ settings|safe|default:"{}" }};{% endautoescape %}
</script>

5) Build an 'injector' that adds code to every request (likely in core/contextprocessors.py)

from models import Setting
import json

def app_settings(request):
    """Global values to pass to templates"""
    settings_dict = dict()
    settings = dict()
    for obj in Setting.objects.all():
        settings[obj.name] = obj.value
    settings_dict['settings'] = json.dumps(settings)
    return settings_dict

5) Then, add the context processors to your site settings.py:

TEMPLATE_CONTEXT_PROCESSORS = (
    ...,
    '<yourapp>.core.contextprocessors.app_settings',
)

6) Log into your admin page via browser and create a setting:

http://yoursite/admin/core/setting/
Add a new setting, something like:
    cell_status_colors
with a value of: 
    ["green","red"] (note this has to be valid JSON, so use quotes around strings)

or:
    daily_header
with a value of:
    {"text":"Tomorrow only, free shipping!"}

7) And finally, each of your javascript files should be able to call these via standard JS:

var colors = site_settings.cell_status_colors || ["green","red"];
var msg_text = site_settings.daily_header || {"text":""};


Ideally, settings.py has to be accessed very rarely, because each access consists in exposing important data (db password for instance). So the best place to store extra settings is definitely a database table - a two column table, with the settings key and the actual settings data will suffice.


There are some applications, that allows django admins to define and use some settings through site-wide... One of those such applications(which i used) is dbsettings...

dbsettings applicaton...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜