from datetime import datetime, date from decimal import Decimal from operator import itemgetter from time import time from django import forms from django.contrib import admin from django.contrib.admin import widgets from django.contrib.admin.options import csrf_protect_m from django.conf import settings from django.conf.urls.defaults import patterns, url from django.core.urlresolvers import reverse from django.forms import fields from django.http import HttpResponseRedirect from django.shortcuts import render_to_response from django.template.context import RequestContext from django.utils.functional import update_wrapper from django.utils.formats import localize from django.utils.translation import ugettext_lazy as _ from constance import config NUMERIC_WIDGET = forms.TextInput(attrs={'size': 10}) INTEGER_LIKE = (fields.IntegerField, {'widget': NUMERIC_WIDGET}) STRING_LIKE = (fields.CharField, {'widget': forms.Textarea(attrs={'rows': 3})}) FIELDS = { bool: (fields.BooleanField, {'required': False}), int: INTEGER_LIKE, long: INTEGER_LIKE, Decimal: (fields.DecimalField, {'widget': NUMERIC_WIDGET}), str: STRING_LIKE, unicode: STRING_LIKE, datetime: (fields.DateTimeField, {'widget': widgets.AdminSplitDateTime}), date: (fields.DateField, {'widget': widgets.AdminDateWidget}), time: (fields.TimeField, {'widget': widgets.AdminTimeWidget}), float: (fields.FloatField, {'widget': NUMERIC_WIDGET}), } class ConstanceForm(forms.Form): def __init__(self, *args, **kwargs): super(ConstanceForm, self).__init__(*args, **kwargs) for name, (default, help_text) in settings.CONSTANCE_CONFIG.items(): field_class, kwargs = FIELDS[type(default)] self.fields[name] = field_class(label=name, **kwargs) def save(self): for name in self.cleaned_data: setattr(config, name, self.cleaned_data[name]) class ConstanceAdmin(admin.ModelAdmin): def get_urls(self): info = self.model._meta.app_label, self.model._meta.module_name return patterns('', url(r'^$', self.admin_site.admin_view(self.changelist_view), name='%s_%s_changelist' % info ), ) @csrf_protect_m def changelist_view(self, request, extra_context=None): form = ConstanceForm(initial=dict((name, getattr(config, name)) for name in settings.CONSTANCE_CONFIG)) if request.method == 'POST': form = ConstanceForm(request.POST) if form.is_valid(): form.save() self.message_user(request, _('Live settings updated successfully.')) return HttpResponseRedirect('.') context = { 'config': [], 'root_path': self.admin_site.root_path, 'title': _('Constance config'), 'app_label': 'constance', 'opts': Config._meta, 'form': form, 'media': self.media + form.media, } for name, (default, help_text) in settings.CONSTANCE_CONFIG.iteritems(): value = getattr(config, name) context['config'].append({ 'name': name, 'default': localize(default), 'help_text': help_text, 'value': localize(value), 'modified': value != default, 'form_field': form[name] }) context['config'].sort(key=itemgetter('name')) context_instance = RequestContext(request, current_app=self.admin_site.name) return render_to_response('admin/constance/change_list.html', context, context_instance=context_instance) def has_add_permission(self, *args, **kwargs): return False def has_delete_permission(self, *args, **kwargs): return False def has_change_permission(self, *args, **kwargs): return True class Config(object): class Meta(object): app_label = 'constance' module_name = 'config' verbose_name_plural = 'config' get_ordered_objects = lambda x: False _meta = Meta() admin.site.register([Config], ConstanceAdmin)