1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-04-27 19:05:16 +00:00

Add django constance to thirdpart to void dependency

This commit is contained in:
zhengxie 2015-10-10 10:51:38 +08:00
parent ba222a9665
commit 18baf34f0e
26 changed files with 1251 additions and 1 deletions

View File

@ -6,4 +6,3 @@ Django>=1.5.8,<1.6
Djblets==0.6.14
django-compressor==1.4
django-statici18n==1.1.2
django-constance[database]

View File

@ -0,0 +1,13 @@
from django.utils.functional import LazyObject
__version__ = '1.0.1'
default_app_config = 'constance.apps.ConstanceConfig'
class LazyConfig(LazyObject):
def _setup(self):
from .base import Config
self._wrapped = Config()
config = LazyConfig()

View File

@ -0,0 +1,187 @@
from datetime import datetime, date, time
from decimal import Decimal
import hashlib
from operator import itemgetter
from django import forms
from django.contrib import admin, messages
from django.contrib.admin import widgets
from django.contrib.admin.options import csrf_protect_m
from django.core.exceptions import PermissionDenied, ImproperlyConfigured
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 import six
from django.utils.formats import localize
from django.utils.translation import ugettext_lazy as _
try:
from django.utils.encoding import smart_bytes
except ImportError:
from django.utils.encoding import smart_str as smart_bytes
try:
from django.conf.urls import patterns, url
except ImportError: # Django < 1.4
from django.conf.urls.defaults import patterns, url
from . import LazyConfig, settings
config = LazyConfig()
NUMERIC_WIDGET = forms.TextInput(attrs={'size': 10})
INTEGER_LIKE = (fields.IntegerField, {'widget': NUMERIC_WIDGET})
STRING_LIKE = (fields.CharField, {
'widget': forms.Textarea(attrs={'rows': 3}),
'required': False,
})
FIELDS = {
bool: (fields.BooleanField, {'required': False}),
int: INTEGER_LIKE,
Decimal: (fields.DecimalField, {'widget': NUMERIC_WIDGET}),
str: 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}),
}
if not six.PY3:
FIELDS.update({
long: INTEGER_LIKE,
unicode: STRING_LIKE,
})
class ConstanceForm(forms.Form):
version = forms.CharField(widget=forms.HiddenInput)
def __init__(self, initial, *args, **kwargs):
super(ConstanceForm, self).__init__(*args, initial=initial, **kwargs)
version_hash = hashlib.md5()
for name, (default, help_text) in settings.CONFIG.items():
config_type = type(default)
if config_type not in FIELDS:
raise ImproperlyConfigured(_("Constance doesn't support "
"config values of the type "
"%(config_type)s. Please fix "
"the value of '%(name)s'.")
% {'config_type': config_type,
'name': name})
field_class, kwargs = FIELDS[config_type]
self.fields[name] = field_class(label=name, **kwargs)
version_hash.update(smart_bytes(initial.get(name, '')))
self.initial['version'] = version_hash.hexdigest()
def save(self):
for name in settings.CONFIG:
setattr(config, name, self.cleaned_data[name])
def clean_version(self):
value = self.cleaned_data['version']
if value != self.initial['version']:
raise forms.ValidationError(_('The settings have been modified '
'by someone else. Please reload the '
'form and resubmit your changes.'))
return value
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),
url(r'^$',
self.admin_site.admin_view(self.changelist_view),
name='%s_%s_add' % info),
)
@csrf_protect_m
def changelist_view(self, request, extra_context=None):
# First load a mapping between config name and default value
if not self.has_change_permission(request, None):
raise PermissionDenied
default_initial = ((name, default)
for name, (default, help_text) in settings.CONFIG.items())
# Then update the mapping with actually values from the backend
initial = dict(default_initial,
**dict(config._backend.mget(settings.CONFIG.keys())))
form = ConstanceForm(initial=initial)
if request.method == 'POST':
form = ConstanceForm(data=request.POST, initial=initial)
if form.is_valid():
form.save()
# In django 1.5 this can be replaced with self.message_user
messages.add_message(
request,
messages.SUCCESS,
_('Live settings updated successfully.'),
)
return HttpResponseRedirect('.')
context = {
'config': [],
'title': _('Constance config'),
'app_label': 'constance',
'opts': Config._meta,
'form': form,
'media': self.media + form.media,
}
for name, (default, help_text) in settings.CONFIG.items():
# First try to load the value from the actual backend
value = initial.get(name)
# Then if the returned value is None, get the default
if value is None:
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, request, obj=None):
if settings.SUPERUSER_ONLY:
return request.user.is_superuser
return super(ConstanceAdmin, self).has_change_permission(request, obj)
class Config(object):
class Meta(object):
app_label = 'constance'
object_name = 'Config'
model_name = module_name = 'config'
verbose_name_plural = _('config')
get_ordered_objects = lambda x: False
abstract = False
swapped = False
def get_change_permission(self):
return 'change_%s' % self.model_name
_meta = Meta()
admin.site.register([Config], ConstanceAdmin)

View File

@ -0,0 +1,7 @@
from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _
class ConstanceConfig(AppConfig):
name = 'constance'
verbose_name = _('Constance')

View File

@ -0,0 +1,26 @@
"""
Defines the base constance backend
"""
class Backend(object):
def get(self, key):
"""
Get the key from the backend store and return the value.
Return None if not found.
"""
raise NotImplementedError
def mget(self, keys):
"""
Get the keys from the backend store and return a list of the values.
Return an empty list if not found.
"""
raise NotImplementedError
def set(self, key, value):
"""
Add the value to the backend store given the key.
"""
raise NotImplementedError

View File

@ -0,0 +1,94 @@
from django.core.exceptions import ImproperlyConfigured
from django.db.models.signals import post_save
from django.core.cache import get_cache
try:
from django.core.cache.backends.locmem import LocMemCache
except ImportError:
from django.core.cache.backends.locmem import CacheClass as LocMemCache
from .. import Backend
from ... import settings
class DatabaseBackend(Backend):
def __init__(self):
from .models import Constance
self._model = Constance
self._prefix = settings.DATABASE_PREFIX
self._autofill_timeout = settings.DATABASE_CACHE_AUTOFILL_TIMEOUT
self._autofill_cachekey = 'autofilled'
if not self._model._meta.installed:
raise ImproperlyConfigured(
"The constance.backends.database app isn't installed "
"correctly. Make sure it's in your INSTALLED_APPS setting.")
if settings.DATABASE_CACHE_BACKEND:
self._cache = get_cache(settings.DATABASE_CACHE_BACKEND)
if isinstance(self._cache, LocMemCache):
raise ImproperlyConfigured(
"The CONSTANCE_DATABASE_CACHE_BACKEND setting refers to a "
"subclass of Django's local-memory backend (%r). Please set "
"it to a backend that supports cross-process caching."
% settings.DATABASE_CACHE_BACKEND)
else:
self._cache = None
self.autofill()
# Clear simple cache.
post_save.connect(self.clear, sender=self._model)
def add_prefix(self, key):
return "%s%s" % (self._prefix, key)
def autofill(self):
if not self._autofill_timeout or not self._cache:
return
full_cachekey = self.add_prefix(self._autofill_cachekey)
if self._cache.get(full_cachekey):
return
autofill_values = {}
autofill_values[full_cachekey] = 1
for key, value in self.mget(settings.CONFIG.keys()):
autofill_values[self.add_prefix(key)] = value
self._cache.set_many(autofill_values, timeout=self._autofill_timeout)
def mget(self, keys):
if not keys:
return
keys = dict((self.add_prefix(key), key) for key in keys)
stored = self._model._default_manager.filter(key__in=keys.keys())
for const in stored:
yield keys[const.key], const.value
def get(self, key):
key = self.add_prefix(key)
if self._cache:
value = self._cache.get(key)
else:
value = None
if value is None:
try:
value = self._model._default_manager.get(key=key).value
except self._model.DoesNotExist:
pass
else:
if self._cache:
self._cache.add(key, value)
return value
def set(self, key, value):
constance, created = self._model._default_manager.get_or_create(
key=self.add_prefix(key), defaults={'value': value}
)
if not created:
constance.value = value
constance.save()
def clear(self, sender, instance, created, **kwargs):
if self._cache and not created:
keys = [self.add_prefix(k)
for k in settings.CONFIG.keys()]
keys.append(self.add_prefix(self._autofill_cachekey))
self._cache.delete_many(keys)
self.autofill()

View File

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import picklefield.fields
class Migration(migrations.Migration):
dependencies = []
operations = [
migrations.CreateModel(
name='Constance',
fields=[
('id', models.AutoField(verbose_name='ID', primary_key=True,
auto_created=True, serialize=False)),
('key', models.CharField(unique=True, max_length=255)),
('value', picklefield.fields.PickledObjectField(editable=False)),
],
options={
'verbose_name': 'constance',
'verbose_name_plural': 'constances',
'db_table': 'constance_config',
},
bases=(models.Model,),
),
]

View File

@ -0,0 +1,24 @@
from django.db import models
from django.core.exceptions import ImproperlyConfigured
from django.utils.translation import ugettext_lazy as _
try:
from picklefield import PickledObjectField
except ImportError:
raise ImproperlyConfigured("Couldn't find the the 3rd party app "
"django-picklefield which is required for "
"the constance database backend.")
class Constance(models.Model):
key = models.CharField(max_length=255, unique=True)
value = PickledObjectField()
class Meta:
verbose_name = _('constance')
verbose_name_plural = _('constances')
db_table = 'constance_config'
def __unicode__(self):
return self.key

View File

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
from south.db import db
from south.v2 import SchemaMigration
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'Constance'
db.create_table('constance_config', (
('id', self.gf('django.db.models.fields.AutoField')(
primary_key=True)),
('key', self.gf('django.db.models.fields.TextField')()),
('value', self.gf('picklefield.fields.PickledObjectField')()),
))
db.send_create_signal('database', ['Constance'])
def backwards(self, orm):
# Deleting model 'Constance'
db.delete_table('constance_config')
models = {
'database.constance': {
'Meta': {'object_name': 'Constance',
'db_table': "'constance_config'"},
'id': ('django.db.models.fields.AutoField', [],
{'primary_key': 'True'}),
'key': ('django.db.models.fields.TextField', [], {}),
'value': ('picklefield.fields.PickledObjectField', [], {})
}
}
complete_apps = ['database']

View File

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
from south.db import db
from south.v2 import SchemaMigration
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'Constance.key'
db.alter_column('constance_config', 'key',
self.gf('django.db.models.fields.CharField')(
max_length=255))
# Adding unique constraint on 'Constance', fields ['key']
db.create_unique('constance_config', ['key'])
def backwards(self, orm):
# Removing unique constraint on 'Constance', fields ['key']
db.delete_unique('constance_config', ['key'])
# Changing field 'Constance.key'
db.alter_column('constance_config', 'key',
self.gf('django.db.models.fields.TextField')())
models = {
'database.constance': {
'Meta': {'object_name': 'Constance',
'db_table': "'constance_config'"},
'id': ('django.db.models.fields.AutoField', [],
{'primary_key': 'True'}),
'key': ('django.db.models.fields.CharField', [],
{'unique': 'True', 'max_length': '255'}),
'value': ('picklefield.fields.PickledObjectField', [], {})
}
}
complete_apps = ['database']

View File

@ -0,0 +1,51 @@
from django.core.exceptions import ImproperlyConfigured
from django.utils import six
from django.utils.six.moves import zip
from . import Backend
from .. import settings, utils
try:
from cPickle import loads, dumps
except ImportError:
from pickle import loads, dumps
class RedisBackend(Backend):
def __init__(self):
super(RedisBackend, self).__init__()
self._prefix = settings.REDIS_PREFIX
connection_cls = settings.REDIS_CONNECTION_CLASS
if connection_cls is not None:
self._rd = utils.import_module_attr(connection_cls)()
else:
try:
import redis
except ImportError:
raise ImproperlyConfigured(
"The Redis backend requires redis-py to be installed.")
if isinstance(settings.REDIS_CONNECTION, six.string_types):
self._rd = redis.from_url(settings.REDIS_CONNECTION)
else:
self._rd = redis.Redis(**settings.REDIS_CONNECTION)
def add_prefix(self, key):
return "%s%s" % (self._prefix, key)
def get(self, key):
value = self._rd.get(self.add_prefix(key))
if value:
return loads(value)
return None
def mget(self, keys):
if not keys:
return
prefixed_keys = [self.add_prefix(key) for key in keys]
for key, value in zip(keys, self._rd.mget(prefixed_keys)):
if value:
yield key, loads(value)
def set(self, key, value):
self._rd.set(self.add_prefix(key), dumps(value))

View File

@ -0,0 +1,30 @@
from . import settings, utils
class Config(object):
"""
The global config wrapper that handles the backend.
"""
def __init__(self):
super(Config, self).__setattr__('_backend',
utils.import_module_attr(settings.BACKEND)())
def __getattr__(self, key):
try:
default, help_text = settings.CONFIG[key]
except KeyError:
raise AttributeError(key)
result = self._backend.get(key)
if result is None:
result = default
setattr(self, key, default)
return result
return result
def __setattr__(self, key, value):
if key not in settings.CONFIG:
raise AttributeError(key)
self._backend.set(key, value)
def __dir__(self):
return settings.CONFIG.keys()

View File

@ -0,0 +1,15 @@
import constance
def config(request):
"""
Simple context processor that puts the config into every
RequestContext. Just make sure you have a setting like this:
TEMPLATE_CONTEXT_PROCESSORS = (
# ...
'constance.context_processors.config',
)
"""
return {"config": constance.config}

View File

@ -0,0 +1,79 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: django-constance\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-11-27 19:05+0100\n"
"PO-Revision-Date: 2014-11-27 18:13+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"Language-Team: Czech (Czech Republic) (http://www.transifex.com/projects/p/django-constance/language/cs_CZ/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: cs_CZ\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
#: admin.py:72
#, python-format
msgid ""
"Constance doesn't support config values of the type %(config_type)s. Please "
"fix the value of '%(name)s'."
msgstr ""
#: admin.py:91
msgid ""
"The settings have been modified by someone else. Please reload the form and "
"resubmit your changes."
msgstr ""
#: admin.py:129
msgid "Live settings updated successfully."
msgstr "Nastavení bylo úspěšně uloženo."
#: admin.py:134
msgid "Constance config"
msgstr "Nastavení konstant"
#: admin.py:177
msgid "config"
msgstr "nastavení"
#: apps.py:9
msgid "Constance"
msgstr ""
#: backends/database/models.py:19
msgid "constance"
msgstr "konstanta"
#: backends/database/models.py:20
msgid "constances"
msgstr "konstanty"
#: templates/admin/constance/change_list.html:50
msgid "Name"
msgstr "Název"
#: templates/admin/constance/change_list.html:51
msgid "Default"
msgstr "Výchozí hodnota"
#: templates/admin/constance/change_list.html:52
msgid "Value"
msgstr "Hodnota"
#: templates/admin/constance/change_list.html:53
msgid "Is modified"
msgstr "Je změněna?"
#: templates/admin/constance/change_list.html:79
msgid "Save"
msgstr "Uložit"
#: templates/admin/constance/change_list.html:89
msgid "Home"
msgstr "Domů"

View File

@ -0,0 +1,80 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Jannis Leidel <jannis@leidel.info>, 2014
msgid ""
msgstr ""
"Project-Id-Version: django-constance\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-11-27 19:05+0100\n"
"PO-Revision-Date: 2014-11-27 18:17+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"Language-Team: German (http://www.transifex.com/projects/p/django-constance/language/de/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: de\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: admin.py:72
#, python-format
msgid ""
"Constance doesn't support config values of the type %(config_type)s. Please "
"fix the value of '%(name)s'."
msgstr "Konstanze unterstützt die Konfigurationswerte vom Typ %(config_type)s nicht. Bitte den Ausgangswert von '%(name)s' ändern."
#: admin.py:91
msgid ""
"The settings have been modified by someone else. Please reload the form and "
"resubmit your changes."
msgstr "Die Konfiguration wurde seit Öffnen dieser Seite verändert. Bitte die Seite neuladen und die Änderungen erneut vornehmen."
#: admin.py:129
msgid "Live settings updated successfully."
msgstr "Die Livekonfiguration wurde erfolgreich aktualisiert."
#: admin.py:134
msgid "Constance config"
msgstr "Constance Konfiguration"
#: admin.py:177
msgid "config"
msgstr "Konfiguration"
#: apps.py:9
msgid "Constance"
msgstr "Konstanze"
#: backends/database/models.py:19
msgid "constance"
msgstr "Konstanze"
#: backends/database/models.py:20
msgid "constances"
msgstr "Konstanzes"
#: templates/admin/constance/change_list.html:50
msgid "Name"
msgstr "Name"
#: templates/admin/constance/change_list.html:51
msgid "Default"
msgstr "Voreinstellung"
#: templates/admin/constance/change_list.html:52
msgid "Value"
msgstr "Wert"
#: templates/admin/constance/change_list.html:53
msgid "Is modified"
msgstr "Ist modifiziert"
#: templates/admin/constance/change_list.html:79
msgid "Save"
msgstr "Sichern"
#: templates/admin/constance/change_list.html:89
msgid "Home"
msgstr "Start"

View File

@ -0,0 +1,79 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-11-27 19:05+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: admin.py:72
#, python-format
msgid ""
"Constance doesn't support config values of the type %(config_type)s. Please "
"fix the value of '%(name)s'."
msgstr ""
#: admin.py:91
msgid ""
"The settings have been modified by someone else. Please reload the form and "
"resubmit your changes."
msgstr ""
#: admin.py:129
msgid "Live settings updated successfully."
msgstr ""
#: admin.py:134
msgid "Constance config"
msgstr ""
#: admin.py:177
msgid "config"
msgstr ""
#: apps.py:9
msgid "Constance"
msgstr ""
#: backends/database/models.py:19
msgid "constance"
msgstr ""
#: backends/database/models.py:20
msgid "constances"
msgstr ""
#: templates/admin/constance/change_list.html:50
msgid "Name"
msgstr ""
#: templates/admin/constance/change_list.html:51
msgid "Default"
msgstr ""
#: templates/admin/constance/change_list.html:52
msgid "Value"
msgstr ""
#: templates/admin/constance/change_list.html:53
msgid "Is modified"
msgstr ""
#: templates/admin/constance/change_list.html:79
msgid "Save"
msgstr ""
#: templates/admin/constance/change_list.html:89
msgid "Home"
msgstr ""

View File

@ -0,0 +1,79 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: django-constance\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-11-27 19:05+0100\n"
"PO-Revision-Date: 2014-11-27 18:13+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"Language-Team: Italian (http://www.transifex.com/projects/p/django-constance/language/it/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: it\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: admin.py:72
#, python-format
msgid ""
"Constance doesn't support config values of the type %(config_type)s. Please "
"fix the value of '%(name)s'."
msgstr ""
#: admin.py:91
msgid ""
"The settings have been modified by someone else. Please reload the form and "
"resubmit your changes."
msgstr ""
#: admin.py:129
msgid "Live settings updated successfully."
msgstr "Le impostazioni attive sono state aggiornate correttamente."
#: admin.py:134
msgid "Constance config"
msgstr "Configurazione Impostazioni"
#: admin.py:177
msgid "config"
msgstr ""
#: apps.py:9
msgid "Constance"
msgstr ""
#: backends/database/models.py:19
msgid "constance"
msgstr "impostazione"
#: backends/database/models.py:20
msgid "constances"
msgstr "impostazioni"
#: templates/admin/constance/change_list.html:50
msgid "Name"
msgstr "Nome"
#: templates/admin/constance/change_list.html:51
msgid "Default"
msgstr "Default"
#: templates/admin/constance/change_list.html:52
msgid "Value"
msgstr "Valore"
#: templates/admin/constance/change_list.html:53
msgid "Is modified"
msgstr "Modificato"
#: templates/admin/constance/change_list.html:79
msgid "Save"
msgstr "Salva"
#: templates/admin/constance/change_list.html:89
msgid "Home"
msgstr "Inizio"

View File

@ -0,0 +1,79 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: django-constance\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-11-27 19:05+0100\n"
"PO-Revision-Date: 2014-11-27 18:13+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"Language-Team: Polish (http://www.transifex.com/projects/p/django-constance/language/pl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pl\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#: admin.py:72
#, python-format
msgid ""
"Constance doesn't support config values of the type %(config_type)s. Please "
"fix the value of '%(name)s'."
msgstr ""
#: admin.py:91
msgid ""
"The settings have been modified by someone else. Please reload the form and "
"resubmit your changes."
msgstr ""
#: admin.py:129
msgid "Live settings updated successfully."
msgstr "Parametry zostały zaktualizowane"
#: admin.py:134
msgid "Constance config"
msgstr "Konfiguracja Constance"
#: admin.py:177
msgid "config"
msgstr ""
#: apps.py:9
msgid "Constance"
msgstr ""
#: backends/database/models.py:19
msgid "constance"
msgstr "parametr"
#: backends/database/models.py:20
msgid "constances"
msgstr "parametry"
#: templates/admin/constance/change_list.html:50
msgid "Name"
msgstr "Nazwa"
#: templates/admin/constance/change_list.html:51
msgid "Default"
msgstr "Domyślnie"
#: templates/admin/constance/change_list.html:52
msgid "Value"
msgstr "Wartość"
#: templates/admin/constance/change_list.html:53
msgid "Is modified"
msgstr "Zmodyfikowana"
#: templates/admin/constance/change_list.html:79
msgid "Save"
msgstr "Zapisz"
#: templates/admin/constance/change_list.html:89
msgid "Home"
msgstr "Początek"

View File

@ -0,0 +1,79 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: django-constance\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-11-27 19:05+0100\n"
"PO-Revision-Date: 2014-11-27 18:13+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"Language-Team: Russian (http://www.transifex.com/projects/p/django-constance/language/ru/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#: admin.py:72
#, python-format
msgid ""
"Constance doesn't support config values of the type %(config_type)s. Please "
"fix the value of '%(name)s'."
msgstr ""
#: admin.py:91
msgid ""
"The settings have been modified by someone else. Please reload the form and "
"resubmit your changes."
msgstr ""
#: admin.py:129
msgid "Live settings updated successfully."
msgstr "Настройки успешно сохранены"
#: admin.py:134
msgid "Constance config"
msgstr "Настройки"
#: admin.py:177
msgid "config"
msgstr "настройки"
#: apps.py:9
msgid "Constance"
msgstr ""
#: backends/database/models.py:19
msgid "constance"
msgstr "настройки"
#: backends/database/models.py:20
msgid "constances"
msgstr "настройки"
#: templates/admin/constance/change_list.html:50
msgid "Name"
msgstr "Название"
#: templates/admin/constance/change_list.html:51
msgid "Default"
msgstr "По умолчанию"
#: templates/admin/constance/change_list.html:52
msgid "Value"
msgstr "Текущее значение"
#: templates/admin/constance/change_list.html:53
msgid "Is modified"
msgstr "Было изменено"
#: templates/admin/constance/change_list.html:79
msgid "Save"
msgstr "Сохранить"
#: templates/admin/constance/change_list.html:89
msgid "Home"
msgstr "Главная"

View File

@ -0,0 +1,79 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: django-constance\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-11-27 19:05+0100\n"
"PO-Revision-Date: 2014-11-27 18:13+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/django-constance/language/zh_CN/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: zh_CN\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: admin.py:72
#, python-format
msgid ""
"Constance doesn't support config values of the type %(config_type)s. Please "
"fix the value of '%(name)s'."
msgstr ""
#: admin.py:91
msgid ""
"The settings have been modified by someone else. Please reload the form and "
"resubmit your changes."
msgstr ""
#: admin.py:129
msgid "Live settings updated successfully."
msgstr "成功更新实时配置"
#: admin.py:134
msgid "Constance config"
msgstr "常量配置"
#: admin.py:177
msgid "config"
msgstr "配置"
#: apps.py:9
msgid "Constance"
msgstr ""
#: backends/database/models.py:19
msgid "constance"
msgstr "常量"
#: backends/database/models.py:20
msgid "constances"
msgstr "常量"
#: templates/admin/constance/change_list.html:50
msgid "Name"
msgstr "名称"
#: templates/admin/constance/change_list.html:51
msgid "Default"
msgstr "默认值"
#: templates/admin/constance/change_list.html:52
msgid "Value"
msgstr "值"
#: templates/admin/constance/change_list.html:53
msgid "Is modified"
msgstr "是否修改"
#: templates/admin/constance/change_list.html:79
msgid "Save"
msgstr "保存"
#: templates/admin/constance/change_list.html:89
msgid "Home"
msgstr "首页"

View File

@ -0,0 +1,24 @@
from django.db.models import signals
def create_perm(app, created_models, verbosity, db, **kwargs):
"""
Creates a fake content type and permission
to be able to check for permissions
"""
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
if ContentType._meta.installed and Permission._meta.installed:
content_type, created = ContentType.objects.get_or_create(
name='config',
app_label='constance',
model='config')
permission, created = Permission.objects.get_or_create(
name='Can change config',
content_type=content_type,
codename='change_config')
signals.post_syncdb.connect(create_perm, dispatch_uid="constance.create_perm")

View File

@ -0,0 +1,24 @@
from django.conf import settings
BACKEND = getattr(settings, 'CONSTANCE_BACKEND',
'constance.backends.redisd.RedisBackend')
CONFIG = getattr(settings, 'CONSTANCE_CONFIG', {})
DATABASE_CACHE_BACKEND = getattr(settings, 'CONSTANCE_DATABASE_CACHE_BACKEND',
None)
DATABASE_CACHE_AUTOFILL_TIMEOUT = getattr(settings,
'CONSTANCE_DATABASE_CACHE_AUTOFILL_TIMEOUT',
60 * 60 * 24)
DATABASE_PREFIX = getattr(settings, 'CONSTANCE_DATABASE_PREFIX', '')
REDIS_PREFIX = getattr(settings, 'CONSTANCE_REDIS_PREFIX', 'constance:')
REDIS_CONNECTION_CLASS = getattr(settings, 'CONSTANCE_REDIS_CONNECTION_CLASS',
None)
REDIS_CONNECTION = getattr(settings, 'CONSTANCE_REDIS_CONNECTION', {})
SUPERUSER_ONLY = getattr(settings, 'CONSTANCE_SUPERUSER_ONLY', True)

View File

@ -0,0 +1,100 @@
{% extends "admin/base_site.html" %}
{% load admin_static admin_list i18n %}
{% load url from future %}
{% block extrastyle %}
{{ block.super }}
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/changelists.css' %}" />
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/forms.css' %}" />
{{ media.css }}
<style>
#result_list .changed {
background-color: #ffc;
}
#changelist table thead th .text {
padding: 2px 5px;
}
#changelist table tbody td:first-child {
text-align: left;
}
#changelist-form ul.errorlist {
margin: 0 !important;
}
.help {
font-weight: normal !important;
}
</style>
{% endblock %}
{% block extrahead %}
{% url 'admin:jsi18n' as jsi18nurl %}
<script type="text/javascript" src="{{ jsi18nurl|default:'../../jsi18n/' }}"></script>
{{ block.super }}
{{ media.js }}
{% endblock %}
{% block bodyclass %}change-list{% endblock %}
{% block content %}
<div id="content-main">
<div class="module" id="changelist">
<form id="changelist-form" action="" method="post">{% csrf_token %}
{% if form.errors %}
<ul class="errorlist">
{% endif %}
{% for field in form.hidden_fields %}
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
{{ field }}
{% endfor %}
{% if form.errors %}
</ul>
{% endif %}
<table cellspacing="0" id="result_list">
<thead>
<tr>
<th><div class="text">{% trans "Name" %}</div></th>
<th><div class="text">{% trans "Default" %}</div></th>
<th><div class="text">{% trans "Value" %}</div></th>
<th><div class="text">{% trans "Is modified" %}</div></th>
</tr>
</thead>
{% for item in config %}
<tr class="{% cycle 'row1' 'row2' %}">
<th>{{ item.name }}
<div class="help">{{ item.help_text }}</div>
</th>
<td>
{{ item.default }}
</td>
<td>
{{ item.form_field.errors }}
{{ item.form_field }}
</td>
<td>
{% if item.modified %}
<img src="{% static 'admin/img/icon-yes.gif' %}" alt="{{ item.modified }}" />
{% else %}
<img src="{% static 'admin/img/icon-no.gif' %}" alt="{{ item.modified }}" />
{% endif %}
</td>
</tr>
{% endfor %}
</table>
<p class="paginator">
<input type="submit" name="_save" class="default" value="{% trans 'Save' %}"/>
</p>
</form>
</div>
</div>
{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ app_label|capfirst|escape }}</a>
&rsaquo; {{ opts.verbose_name_plural|capfirst }}
</div>
{% endblock %}

View File

@ -0,0 +1,6 @@
from django.utils.importlib import import_module
def import_module_attr(path):
package, module = path.rsplit('.', 1)
return getattr(import_module(package), module)