From 7d01f2377e7d52494caeb4b5b4a6137105f006cf Mon Sep 17 00:00:00 2001 From: "Dmitry.Shelepnev" Date: Thu, 30 Aug 2018 21:04:20 +0300 Subject: [PATCH] Django-constance package integrate in project from github. --- .travis.yml | 3 +- constance/__init__.py | 14 + constance/admin.py | 327 ++++++++++++++++++ constance/apps.py | 35 ++ constance/backends/__init__.py | 26 ++ constance/backends/database/__init__.py | 109 ++++++ .../database/migrations/0001_initial.py | 27 ++ .../backends/database/migrations/__init__.py | 0 constance/backends/database/models.py | 24 ++ .../database/south_migrations/0001_initial.py | 33 ++ ...constance_key__add_unique_constance_key.py | 36 ++ .../database/south_migrations/__init__.py | 0 constance/backends/redisd.py | 55 +++ constance/base.py | 32 ++ constance/context_processors.py | 15 + constance/locale/cs_CZ/LC_MESSAGES/django.mo | Bin 0 -> 987 bytes constance/locale/cs_CZ/LC_MESSAGES/django.po | 96 +++++ constance/locale/de/LC_MESSAGES/django.mo | Bin 0 -> 1482 bytes constance/locale/de/LC_MESSAGES/django.po | 106 ++++++ constance/locale/en/LC_MESSAGES/django.mo | Bin 0 -> 378 bytes constance/locale/en/LC_MESSAGES/django.po | 92 +++++ constance/locale/es/LC_MESSAGES/django.mo | Bin 0 -> 1474 bytes constance/locale/es/LC_MESSAGES/django.po | 106 ++++++ constance/locale/et/LC_MESSAGES/django.mo | Bin 0 -> 1717 bytes constance/locale/et/LC_MESSAGES/django.po | 99 ++++++ constance/locale/fr/LC_MESSAGES/django.mo | Bin 0 -> 1872 bytes constance/locale/fr/LC_MESSAGES/django.po | 95 +++++ constance/locale/it/LC_MESSAGES/django.mo | Bin 0 -> 1879 bytes constance/locale/it/LC_MESSAGES/django.po | 105 ++++++ constance/locale/pl/LC_MESSAGES/django.mo | Bin 0 -> 1010 bytes constance/locale/pl/LC_MESSAGES/django.po | 97 ++++++ constance/locale/ru/LC_MESSAGES/django.mo | Bin 0 -> 1126 bytes constance/locale/ru/LC_MESSAGES/django.po | 97 ++++++ constance/locale/zh_CN/LC_MESSAGES/django.mo | Bin 0 -> 1368 bytes constance/locale/zh_CN/LC_MESSAGES/django.po | 100 ++++++ .../locale/zh_Hans/LC_MESSAGES/django.mo | Bin 0 -> 1909 bytes .../locale/zh_Hans/LC_MESSAGES/django.po | 97 ++++++ constance/management/__init__.py | 0 constance/management/commands/__init__.py | 0 constance/management/commands/constance.py | 77 +++++ constance/settings.py | 45 +++ constance/signals.py | 5 + constance/static/admin/css/constance.css | 15 + constance/static/admin/js/constance.js | 26 ++ .../admin/constance/change_list.html | 73 ++++ .../constance/includes/results_list.html | 49 +++ constance/test/__init__.py | 1 + constance/test/utils.py | 85 +++++ constance/utils.py | 6 + requirements.txt | 4 +- 50 files changed, 2209 insertions(+), 3 deletions(-) create mode 100644 constance/__init__.py create mode 100644 constance/admin.py create mode 100644 constance/apps.py create mode 100644 constance/backends/__init__.py create mode 100644 constance/backends/database/__init__.py create mode 100644 constance/backends/database/migrations/0001_initial.py create mode 100644 constance/backends/database/migrations/__init__.py create mode 100644 constance/backends/database/models.py create mode 100644 constance/backends/database/south_migrations/0001_initial.py create mode 100644 constance/backends/database/south_migrations/0002_auto__chg_field_constance_key__add_unique_constance_key.py create mode 100644 constance/backends/database/south_migrations/__init__.py create mode 100644 constance/backends/redisd.py create mode 100644 constance/base.py create mode 100644 constance/context_processors.py create mode 100644 constance/locale/cs_CZ/LC_MESSAGES/django.mo create mode 100644 constance/locale/cs_CZ/LC_MESSAGES/django.po create mode 100644 constance/locale/de/LC_MESSAGES/django.mo create mode 100644 constance/locale/de/LC_MESSAGES/django.po create mode 100644 constance/locale/en/LC_MESSAGES/django.mo create mode 100644 constance/locale/en/LC_MESSAGES/django.po create mode 100644 constance/locale/es/LC_MESSAGES/django.mo create mode 100644 constance/locale/es/LC_MESSAGES/django.po create mode 100644 constance/locale/et/LC_MESSAGES/django.mo create mode 100644 constance/locale/et/LC_MESSAGES/django.po create mode 100644 constance/locale/fr/LC_MESSAGES/django.mo create mode 100644 constance/locale/fr/LC_MESSAGES/django.po create mode 100644 constance/locale/it/LC_MESSAGES/django.mo create mode 100644 constance/locale/it/LC_MESSAGES/django.po create mode 100644 constance/locale/pl/LC_MESSAGES/django.mo create mode 100644 constance/locale/pl/LC_MESSAGES/django.po create mode 100644 constance/locale/ru/LC_MESSAGES/django.mo create mode 100644 constance/locale/ru/LC_MESSAGES/django.po create mode 100644 constance/locale/zh_CN/LC_MESSAGES/django.mo create mode 100644 constance/locale/zh_CN/LC_MESSAGES/django.po create mode 100644 constance/locale/zh_Hans/LC_MESSAGES/django.mo create mode 100644 constance/locale/zh_Hans/LC_MESSAGES/django.po create mode 100644 constance/management/__init__.py create mode 100644 constance/management/commands/__init__.py create mode 100644 constance/management/commands/constance.py create mode 100644 constance/settings.py create mode 100644 constance/signals.py create mode 100644 constance/static/admin/css/constance.css create mode 100644 constance/static/admin/js/constance.js create mode 100644 constance/templates/admin/constance/change_list.html create mode 100644 constance/templates/admin/constance/includes/results_list.html create mode 100644 constance/test/__init__.py create mode 100644 constance/test/utils.py create mode 100644 constance/utils.py diff --git a/.travis.yml b/.travis.yml index c2acafb..5a464da 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,11 +3,12 @@ python: - 3.4 - 3.5 - 3.6 + - 3.7 env: - DJANGO='django>=1.10,<1.11' - DJANGO='django>=1.11,<2.0' - - DJANGO='django>=2.0,<2.1' + - DJANGO='django>=2.0' install: - travis_retry pip install $DJANGO diff --git a/constance/__init__.py b/constance/__init__.py new file mode 100644 index 0000000..ac30b72 --- /dev/null +++ b/constance/__init__.py @@ -0,0 +1,14 @@ +from django.utils.functional import LazyObject + +__version__ = '2.2.0' + +default_app_config = 'constance.apps.ConstanceConfig' + + +class LazyConfig(LazyObject): + def _setup(self): + from .base import Config + self._wrapped = Config() + + +config = LazyConfig() diff --git a/constance/admin.py b/constance/admin.py new file mode 100644 index 0000000..a2285cc --- /dev/null +++ b/constance/admin.py @@ -0,0 +1,327 @@ +from collections import OrderedDict +from datetime import datetime, date, time, timedelta +from decimal import Decimal +from operator import itemgetter +import hashlib +import os + +from django import forms, VERSION +from django.apps import apps +from django.conf import settings as django_settings +from django.conf.urls import url +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.template.response import TemplateResponse +from django.utils import six +from django.utils.encoding import smart_bytes +from django.utils.formats import localize +from django.utils.module_loading import import_string +from django.utils.translation import ugettext_lazy as _ + +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.SplitDateTimeField, {'widget': widgets.AdminSplitDateTime} + ), + timedelta: ( + fields.DurationField, {'widget': widgets.AdminTextInputWidget} + ), + date: (fields.DateField, {'widget': widgets.AdminDateWidget}), + time: (fields.TimeField, {'widget': widgets.AdminTimeWidget}), + float: (fields.FloatField, {'widget': NUMERIC_WIDGET}), +} + + +def parse_additional_fields(fields): + for key in fields: + field = list(fields[key]) + + if len(field) == 1: + field.append({}) + + field[0] = import_string(field[0]) + + if 'widget' in field[1]: + klass = import_string(field[1]['widget']) + field[1]['widget'] = klass( + **(field[1].get('widget_kwargs', {}) or {}) + ) + + if 'widget_kwargs' in field[1]: + del field[1]['widget_kwargs'] + + fields[key] = field + + return fields + + +FIELDS.update(parse_additional_fields(settings.ADDITIONAL_FIELDS)) + +if not six.PY3: + FIELDS.update({ + long: INTEGER_LIKE, + unicode: STRING_LIKE, + }) + + +def get_values(): + """ + Get dictionary of values from the backend + :return: + """ + + # First load a mapping between config name and default value + default_initial = ((name, options[0]) + for name, options in settings.CONFIG.items()) + # Then update the mapping with actually values from the backend + initial = dict(default_initial, **dict(config._backend.mget(settings.CONFIG))) + + return initial + + +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, options in settings.CONFIG.items(): + default = options[0] + if len(options) == 3: + config_type = options[2] + if config_type not in settings.ADDITIONAL_FIELDS and not isinstance(default, config_type): + raise ImproperlyConfigured(_("Default value type must be " + "equal to declared config " + "parameter type. Please fix " + "the default value of " + "'%(name)s'.") + % {'name': name}) + else: + 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 file_field in self.files: + file = self.cleaned_data[file_field] + file_path = os.path.join(django_settings.MEDIA_ROOT, file.name) + with open(file_path, 'wb+') as destination: + for chunk in file.chunks(): + destination.write(chunk) + self.cleaned_data[file_field] = file.name + + for name in settings.CONFIG: + if getattr(config, name) != self.cleaned_data[name]: + setattr(config, name, self.cleaned_data[name]) + + def clean_version(self): + value = self.cleaned_data['version'] + + if settings.IGNORE_ADMIN_VERSION_CHECK: + return value + + 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 + + def clean(self): + cleaned_data = super(ConstanceForm, self).clean() + + if not settings.CONFIG_FIELDSETS: + return cleaned_data + + field_name_list = [] + for fieldset_title, fields_list in settings.CONFIG_FIELDSETS.items(): + for field_name in fields_list: + field_name_list.append(field_name) + if field_name_list and set(set(settings.CONFIG.keys()) - set(field_name_list)): + raise forms.ValidationError(_('CONSTANCE_CONFIG_FIELDSETS is missing ' + 'field(s) that exists in CONSTANCE_CONFIG.')) + + return cleaned_data + + +class ConstanceAdmin(admin.ModelAdmin): + change_list_template = 'admin/constance/change_list.html' + change_list_form = ConstanceForm + + def get_urls(self): + info = self.model._meta.app_label, self.model._meta.module_name + return [ + 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), + ] + + def get_config_value(self, name, options, form, initial): + default, help_text = options[0], options[1] + # 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) + config_value = { + 'name': name, + 'default': localize(default), + 'raw_default': default, + 'help_text': _(help_text), + 'value': localize(value), + 'modified': localize(value) != localize(default), + 'form_field': form[name], + 'is_date': isinstance(default, date), + 'is_datetime': isinstance(default, datetime), + 'is_checkbox': isinstance(form[name].field.widget, forms.CheckboxInput), + 'is_file': isinstance(form[name].field.widget, forms.FileInput), + } + + return config_value + + def get_changelist_form(self, request): + """ + Returns a Form class for use in the changelist_view. + """ + # Defaults to self.change_list_form in order to preserve backward + # compatibility + return self.change_list_form + + @csrf_protect_m + def changelist_view(self, request, extra_context=None): + if not self.has_change_permission(request, None): + raise PermissionDenied + initial = get_values() + form_cls = self.get_changelist_form(request) + form = form_cls(initial=initial) + if request.method == 'POST': + form = form_cls( + data=request.POST, files=request.FILES, initial=initial + ) + if form.is_valid(): + form.save() + messages.add_message( + request, + messages.SUCCESS, + _('Live settings updated successfully.'), + ) + return HttpResponseRedirect('.') + context = dict( + self.admin_site.each_context(request), + config_values=[], + title=self.model._meta.app_config.verbose_name, + app_label='constance', + opts=self.model._meta, + form=form, + media=self.media + form.media, + icon_type='gif' if VERSION < (1, 9) else 'svg', + ) + for name, options in settings.CONFIG.items(): + context['config_values'].append( + self.get_config_value(name, options, form, initial) + ) + + if settings.CONFIG_FIELDSETS: + context['fieldsets'] = [] + for fieldset_title, fields_list in settings.CONFIG_FIELDSETS.items(): + fields_exist = all(field in settings.CONFIG for field in fields_list) + assert fields_exist, "CONSTANCE_CONFIG_FIELDSETS contains field(s) that does not exist" + config_values = [] + + for name in fields_list: + options = settings.CONFIG.get(name) + if options: + config_values.append( + self.get_config_value(name, options, form, initial) + ) + + context['fieldsets'].append({ + 'title': fieldset_title, + 'config_values': config_values + }) + if not isinstance(settings.CONFIG_FIELDSETS, OrderedDict): + context['fieldsets'].sort(key=itemgetter('title')) + + if not isinstance(settings.CONFIG, OrderedDict): + context['config_values'].sort(key=itemgetter('name')) + request.current_app = self.admin_site.name + return TemplateResponse(request, self.change_list_template, context) + + 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') + abstract = False + swapped = False + + def get_ordered_objects(self): + return False + + def get_change_permission(self): + return 'change_%s' % self.model_name + + @property + def app_config(self): + return apps.get_app_config(self.app_label) + + @property + def label(self): + return '%s.%s' % (self.app_label, self.object_name) + + @property + def label_lower(self): + return '%s.%s' % (self.app_label, self.model_name) + + _meta = Meta() + + +admin.site.register([Config], ConstanceAdmin) diff --git a/constance/apps.py b/constance/apps.py new file mode 100644 index 0000000..25099a8 --- /dev/null +++ b/constance/apps.py @@ -0,0 +1,35 @@ +from django.db.models import signals +from django.apps import AppConfig + + +class ConstanceConfig(AppConfig): + name = 'constance' + verbose_name = 'Constance' + + def ready(self): + super(ConstanceConfig, self).ready() + signals.post_migrate.connect(self.create_perm, + dispatch_uid='constance.create_perm') + + def create_perm(self, using=None, *args, **kwargs): + """ + Creates a fake content type and permission + to be able to check for permissions + """ + from django.conf import settings + from django.contrib.auth.models import Permission + from django.contrib.contenttypes.models import ContentType + + constance_dbs = getattr(settings, 'CONSTANCE_DBS', None) + if constance_dbs is not None and using not in constance_dbs: + return + if ContentType._meta.installed and Permission._meta.installed: + content_type, created = ContentType.objects.using(using).get_or_create( + app_label='constance', + model='config', + ) + + permission, created = Permission.objects.using(using).get_or_create( + content_type=content_type, + codename='change_config', + defaults={'name': 'Can change config'}) diff --git a/constance/backends/__init__.py b/constance/backends/__init__.py new file mode 100644 index 0000000..a64905e --- /dev/null +++ b/constance/backends/__init__.py @@ -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 diff --git a/constance/backends/database/__init__.py b/constance/backends/database/__init__.py new file mode 100644 index 0000000..454b500 --- /dev/null +++ b/constance/backends/database/__init__.py @@ -0,0 +1,109 @@ +from django.core.cache import caches +from django.core.cache.backends.locmem import LocMemCache +from django.core.exceptions import ImproperlyConfigured +from django.db import OperationalError, ProgrammingError +from django.db.models.signals import post_save + +from .. import Backend +from ... import settings, signals, config + + +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 = caches[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): + 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 = {self.add_prefix(key): key for key in keys} + try: + stored = self._model._default_manager.filter(key__in=keys) + for const in stored: + yield keys[const.key], const.value + except (OperationalError, ProgrammingError): + pass + + def get(self, key): + key = self.add_prefix(key) + if self._cache: + value = self._cache.get(key) + if value is None: + self.autofill() + value = self._cache.get(key) + else: + value = None + if value is None: + try: + value = self._model._default_manager.get(key=key).value + except (OperationalError, ProgrammingError, self._model.DoesNotExist): + pass + else: + if self._cache: + self._cache.add(key, value) + return value + + def set(self, key, value): + old_value = self.get(key) + + try: + constance, created = self._model._default_manager.get_or_create( + key=self.add_prefix(key), defaults={'value': value} + ) + except (OperationalError, ProgrammingError): + # database is not created, noop + return + + if not created: + constance.value = value + constance.save() + if self._cache: + self._cache.set(key, value) + + signals.config_updated.send( + sender=config, key=key, old_value=old_value, new_value=value + ) + + def clear(self, sender, instance, created, **kwargs): + if self._cache and not created: + keys = [self.add_prefix(k) for k in settings.CONFIG] + keys.append(self.add_prefix(self._autofill_cachekey)) + self._cache.delete_many(keys) + self.autofill() diff --git a/constance/backends/database/migrations/0001_initial.py b/constance/backends/database/migrations/0001_initial.py new file mode 100644 index 0000000..e0ebd99 --- /dev/null +++ b/constance/backends/database/migrations/0001_initial.py @@ -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,), + ), + ] diff --git a/constance/backends/database/migrations/__init__.py b/constance/backends/database/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/constance/backends/database/models.py b/constance/backends/database/models.py new file mode 100644 index 0000000..e9964e8 --- /dev/null +++ b/constance/backends/database/models.py @@ -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 diff --git a/constance/backends/database/south_migrations/0001_initial.py b/constance/backends/database/south_migrations/0001_initial.py new file mode 100644 index 0000000..f9b7473 --- /dev/null +++ b/constance/backends/database/south_migrations/0001_initial.py @@ -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'] diff --git a/constance/backends/database/south_migrations/0002_auto__chg_field_constance_key__add_unique_constance_key.py b/constance/backends/database/south_migrations/0002_auto__chg_field_constance_key__add_unique_constance_key.py new file mode 100644 index 0000000..ef8fb3c --- /dev/null +++ b/constance/backends/database/south_migrations/0002_auto__chg_field_constance_key__add_unique_constance_key.py @@ -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'] diff --git a/constance/backends/database/south_migrations/__init__.py b/constance/backends/database/south_migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/constance/backends/redisd.py b/constance/backends/redisd.py new file mode 100644 index 0000000..c7d522e --- /dev/null +++ b/constance/backends/redisd.py @@ -0,0 +1,55 @@ +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, signals, config + +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): + old_value = self.get(key) + self._rd.set(self.add_prefix(key), dumps(value)) + signals.config_updated.send( + sender=config, key=key, old_value=old_value, new_value=value + ) diff --git a/constance/base.py b/constance/base.py new file mode 100644 index 0000000..e44ff75 --- /dev/null +++ b/constance/base.py @@ -0,0 +1,32 @@ +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: + if not len(settings.CONFIG[key]) in (2, 3): + raise AttributeError(key) + default = settings.CONFIG[key][0] + 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() diff --git a/constance/context_processors.py b/constance/context_processors.py new file mode 100644 index 0000000..3a3da33 --- /dev/null +++ b/constance/context_processors.py @@ -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} diff --git a/constance/locale/cs_CZ/LC_MESSAGES/django.mo b/constance/locale/cs_CZ/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..4c9010077e4c79177133f60f34ddbb80297eb5bb GIT binary patch literal 987 zcmca7#4?qEfq{XWfq_AWfq|iffq_Agfq~%+NRWYnL4c8gfgL2q$iTqDz`!8M2vIA? z$iSe?z`&pd759VE!Hf(HtPBhc5sVBBYzzzxaf}QMoD2*Msf-K^Tnr2h`HTz<_ZS%% zsu&^mL^4CvXEQS}@G>wk6f!d~s4_4x)H6f$FJ*?JN~8Q0K!bkRL!C4hD!nKyG7VfY{B<05KCJ&)|}pmROoo!r+mgo66u>tdN_Zl9`s7 zn!@0dS(d6$oLW+nnU`LyP+E|ZSdyBeP+XdvoLXF*R+^JjsmI`#n48KFoLH915SExz zn#z!zpO==I4x)-n67!P50uWX)LqJh}R%&vIu4jsFSZYymW`3TPLP}O*UV6T6a(*5} z6<1JdL4Hw*u5WRAW{R#;X?n44NWPTRP(i5$rAaxN$(jlp86_nJR{Hwo<>h)MAPX|nQY-Y5^KuZ6s#09^6YGl6x7rd@@#BPK!Sz}RtiSeTnu4{ z_a@<{e(EkW`tI zuW)!*alw(\n" +"Language-Team: Czech (Czech Republic) (http://www.transifex.com/projects/p/" +"django-constance/language/cs_CZ/)\n" +"Language: cs_CZ\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" + +#: admin.py:113 +#, python-format +msgid "" +"Default value type must be equal to declared config parameter type. Please " +"fix the default value of '%(name)s'." +msgstr "" + +#: admin.py:123 +#, 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:147 +msgid "" +"The settings have been modified by someone else. Please reload the form and " +"resubmit your changes." +msgstr "" + +#: admin.py:160 +msgid "" +"CONSTANCE_CONFIG_FIELDSETS does not contain fields that exist in " +"CONSTANCE_CONFIG." +msgstr "" + +#: admin.py:224 +msgid "Live settings updated successfully." +msgstr "Nastavení bylo úspěšně uloženo." + +#: admin.py:285 +msgid "config" +msgstr "nastavení" + +#: apps.py:8 +msgid "Constance" +msgstr "" + +#: backends/database/models.py:19 +msgid "constance" +msgstr "konstanta" + +#: backends/database/models.py:20 +msgid "constances" +msgstr "konstanty" + +#: management/commands/constance.py:30 +msgid "Get/Set In-database config settings handled by Constance" +msgstr "" + +#: templates/admin/constance/change_list.html:75 +msgid "Save" +msgstr "Uložit" + +#: templates/admin/constance/change_list.html:84 +msgid "Home" +msgstr "Domů" + +#: templates/admin/constance/includes/results_list.html:5 +msgid "Name" +msgstr "Název" + +#: templates/admin/constance/includes/results_list.html:6 +msgid "Default" +msgstr "Výchozí hodnota" + +#: templates/admin/constance/includes/results_list.html:7 +msgid "Value" +msgstr "Hodnota" + +#: templates/admin/constance/includes/results_list.html:8 +msgid "Is modified" +msgstr "Je změněna?" + +#~ msgid "Constance config" +#~ msgstr "Nastavení konstant" diff --git a/constance/locale/de/LC_MESSAGES/django.mo b/constance/locale/de/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..a0d65980fd11bcbf397dc61f6225c159ad5c8c52 GIT binary patch literal 1482 zcmca7#4?qEfq{XKfq_AWfq|iifq_Aofq~%3fs=uO!IP1JA%lT|A()YY zft`VYVGkn%0}BHK!x2UX25trhhLem849W})3|FDzKcVzLMh1o?1_lOZCI$vp1_p*S zCI$vJ1_p*4CWyJkObiTM3=9mlObiTb85tNlpyFmM3=B043=9q|5V!4Rf#^TO!oa}K zz`$^cg@M78fq~%>3&b4~tPpp}vO@H!vO>fcu`)35GB7YKXNB0el@(&&epUtsMyS6* z@*wYWFhI-zu|aNSVt}Xx`48k*W(J5EAbF4EtLrhiq^2d7=9DmaVIUtfK)eW|pdpnE3$tQ|fTH}Y)Z`Lf&lKIT)S}|d{5&g#l&r+O z^n6{oDz2bZP%!HH7N=*X=sK0A7wd-PTPbh__=o5^7o{eaWaj7Tx+IpQS}7PA7@F%E znCTiCD;Qc@nHXprm>L^!1^DX*rIuxaOh>3Q(KR&GH8NK)w6HQX*ETRPFyQh@EH2Rv zDN4*M&PgoEFS1hbO3cg4ELQMI%}hznQLxDZa~*QPT)oV^w0t`*pTxZM(!}&s-H_D8 zTq_0l)S}$PJOz!6l9B=|ef{$Ca=j9efthKk6?)0}x%veV4;Skf=%f2nKL=`-eoCso zCfsBzg_Kk-Ur%3GLhe z)yPv&v{f+FwB};)hD2OdDuSg@npcuqR9td+Pf1mYLP}<;f;Tv|mllEJrMNt`s3cXP zEI(Hvq_O}#y({EpCTEoBDL7@8l%y)8q~<9&mKLWc=B0zRDU{{sDIgNQ!r>)(DXB$y zdJJLtMX8y2#U-gZIi-2&48bLdMI{WL#U;?RTa}qwRKnnrnW_NF5ZTDiQ7A7hN=a2n zElSJJNiRyxOwLe9%q}TS%*iYUX@X^s%;b#JqCBt>D87MeFHX%YQ8+v;EiErK59HPx# literal 0 HcmV?d00001 diff --git a/constance/locale/de/LC_MESSAGES/django.po b/constance/locale/de/LC_MESSAGES/django.po new file mode 100644 index 0000000..705ab1e --- /dev/null +++ b/constance/locale/de/LC_MESSAGES/django.po @@ -0,0 +1,106 @@ +# 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 , 2014 +msgid "" +msgstr "" +"Project-Id-Version: django-constance\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-06-13 19:40+0530\n" +"PO-Revision-Date: 2014-11-27 18:17+0000\n" +"Last-Translator: Jannis Leidel \n" +"Language-Team: German (http://www.transifex.com/projects/p/django-constance/" +"language/de/)\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: admin.py:113 +#, fuzzy, python-format +#| msgid "" +#| "Constance doesn't support config values of the type %(config_type)s. " +#| "Please fix the value of '%(name)s'." +msgid "" +"Default value type must be equal to declared config parameter type. Please " +"fix the default 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:123 +#, 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:147 +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:160 +msgid "" +"CONSTANCE_CONFIG_FIELDSETS does not contain fields that exist in " +"CONSTANCE_CONFIG." +msgstr "" + +#: admin.py:224 +msgid "Live settings updated successfully." +msgstr "Die Livekonfiguration wurde erfolgreich aktualisiert." + +#: admin.py:285 +msgid "config" +msgstr "Konfiguration" + +#: apps.py:8 +msgid "Constance" +msgstr "Konstanze" + +#: backends/database/models.py:19 +msgid "constance" +msgstr "Konstanze" + +#: backends/database/models.py:20 +msgid "constances" +msgstr "Konstanzes" + +#: management/commands/constance.py:30 +msgid "Get/Set In-database config settings handled by Constance" +msgstr "" + +#: templates/admin/constance/change_list.html:75 +msgid "Save" +msgstr "Sichern" + +#: templates/admin/constance/change_list.html:84 +msgid "Home" +msgstr "Start" + +#: templates/admin/constance/includes/results_list.html:5 +msgid "Name" +msgstr "Name" + +#: templates/admin/constance/includes/results_list.html:6 +msgid "Default" +msgstr "Voreinstellung" + +#: templates/admin/constance/includes/results_list.html:7 +msgid "Value" +msgstr "Wert" + +#: templates/admin/constance/includes/results_list.html:8 +msgid "Is modified" +msgstr "Ist modifiziert" + +#~ msgid "Constance config" +#~ msgstr "Constance Konfiguration" diff --git a/constance/locale/en/LC_MESSAGES/django.mo b/constance/locale/en/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..8319b4801f99dc60951c0488fa290c61e3d47cfe GIT binary patch literal 378 zcmca7#4?qEfq{XMfq_AWfq_AVfq{XUfq_8>B*?(PV8Ot^;K0bhUKLT!>#ytLsNmsm(Eqz&;u7Q<9BjwslbDxYnwXxd8, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-06-13 19:40+0530\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: admin.py:113 +#, python-format +msgid "" +"Default value type must be equal to declared config parameter type. Please " +"fix the default value of '%(name)s'." +msgstr "" + +#: admin.py:123 +#, 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:147 +msgid "" +"The settings have been modified by someone else. Please reload the form and " +"resubmit your changes." +msgstr "" + +#: admin.py:160 +msgid "" +"CONSTANCE_CONFIG_FIELDSETS does not contain fields that exist in " +"CONSTANCE_CONFIG." +msgstr "" + +#: admin.py:224 +msgid "Live settings updated successfully." +msgstr "" + +#: admin.py:285 +msgid "config" +msgstr "" + +#: apps.py:8 +msgid "Constance" +msgstr "" + +#: backends/database/models.py:19 +msgid "constance" +msgstr "" + +#: backends/database/models.py:20 +msgid "constances" +msgstr "" + +#: management/commands/constance.py:30 +msgid "Get/Set In-database config settings handled by Constance" +msgstr "" + +#: templates/admin/constance/change_list.html:75 +msgid "Save" +msgstr "" + +#: templates/admin/constance/change_list.html:84 +msgid "Home" +msgstr "" + +#: templates/admin/constance/includes/results_list.html:5 +msgid "Name" +msgstr "" + +#: templates/admin/constance/includes/results_list.html:6 +msgid "Default" +msgstr "" + +#: templates/admin/constance/includes/results_list.html:7 +msgid "Value" +msgstr "" + +#: templates/admin/constance/includes/results_list.html:8 +msgid "Is modified" +msgstr "" diff --git a/constance/locale/es/LC_MESSAGES/django.mo b/constance/locale/es/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..55a6b6c0d3f0518ed8970c636f6fecf3139d9928 GIT binary patch literal 1474 zcmca7#4?qEfq{XKfq_AWfq|iifq_Aofq~%3fs=uO!IP1JA%lT|A()YY zft`VYVGkn%0}BHK!x2UX25trhhLem849W})3|FDzKcVzLMh1o?1_lOZCI$vp1_p*S zCI$vJ1_p*4CWyJkObiTM3=9mlObiU`7#SEkpyK8%3=Cxq3=EDe5V!4Mf#^HV!oVQF zz`$^hg@M76fq~&ZR9uo3;w}YN28MhF1_ljQh;%OG^DFo!CCKjhE zq-9os6@j&Ybf~LpOF}S3rC6?xtFnHwWrZRXIE9B;M{5w=B6?PCzho$gk&Ho&PXgvRY*!r z&4Zh!kW{HqoS&PTpO>nTnp2z#cUw_vPJUtv*m-IBMY#%zc_|7-sl}y9xtS#jmHDMb z3dtFXdFiRedJJJ8A2UF_2%?}Nl?)5BVupaC{H)aE5?#*}-LTZ6;>`R!D}?|@XKzP$ zSA{UwpkPmbKdzuuP$=s97N=*X=sK0A7wd-PTPbh__=o5^7o{eaWaj7Tx+IpQS}7PA z7@F%EnCTiCD;Qc@nHXprm>L^!1^DX*rIuxa42P%Ph`N(8wq$DX`MlFE20GD*>6AnU-3imz*ZCdcH0^JoIy*hUurI>cdU8Qb;Z4^7Zs}MFf$do&lG0eqKpxUWsl&N5b8j#NJ}l!bpQphU+bBk?_tQ8I zC^aRuB(*3vGcPeEpTRRPGdVM#!L_*L@Iq+HO$LekBo-sPAU`j)SRpk}p)9j3U!gcv zAu+k6G%+W$DzPX(Pa(A;vn0PbF*h}@Bvp^WFF!Y_D3!szG_fcpv53JZ5!oD&Pcjk} ziZfI45w;~N6o4F_lU|w$%07n|g0eB(Lq(~{iACw9U>||9OKDDGQD(kEr9x3^YF^pl iwW$ilrNs)#iMdIc`H&owUj)i3X_@J;zyonHa}EH;TdGt5 literal 0 HcmV?d00001 diff --git a/constance/locale/es/LC_MESSAGES/django.po b/constance/locale/es/LC_MESSAGES/django.po new file mode 100644 index 0000000..43b2b88 --- /dev/null +++ b/constance/locale/es/LC_MESSAGES/django.po @@ -0,0 +1,106 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Igor Támara , 2015 +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-06-13 19:40+0530\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Igor Támara \n" +"Language-Team: Spanish (http://www.transifex.com/projects/p/django-constance/" +"language/de/\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: admin.py:113 +#, fuzzy, python-format +#| msgid "" +#| "Constance doesn't support config values of the type %(config_type)s. " +#| "Please fix the value of '%(name)s'." +msgid "" +"Default value type must be equal to declared config parameter type. Please " +"fix the default value of '%(name)s'." +msgstr "" +"Constance no soporta valores de configuración de los tipos %(config_type)s. " +"Por favor arregle el valor de '%(name)s'." + +#: admin.py:123 +#, python-format +msgid "" +"Constance doesn't support config values of the type %(config_type)s. Please " +"fix the value of '%(name)s'." +msgstr "" +"Constance no soporta valores de configuración de los tipos %(config_type)s. " +"Por favor arregle el valor de '%(name)s'." + +#: admin.py:147 +msgid "" +"The settings have been modified by someone else. Please reload the form and " +"resubmit your changes." +msgstr "" +"La configuración ha sido modificada por alguien más. Por favor recargue el " +"formulario y reenvíe sus cambios." + +#: admin.py:160 +msgid "" +"CONSTANCE_CONFIG_FIELDSETS does not contain fields that exist in " +"CONSTANCE_CONFIG." +msgstr "" + +#: admin.py:224 +msgid "Live settings updated successfully." +msgstr "Las configuraciones en vivo se actualizaron exitosamente." + +#: admin.py:285 +msgid "config" +msgstr "configuración" + +#: apps.py:8 +msgid "Constance" +msgstr "Constance" + +#: backends/database/models.py:19 +msgid "constance" +msgstr "constance" + +#: backends/database/models.py:20 +msgid "constances" +msgstr "constances" + +#: management/commands/constance.py:30 +msgid "Get/Set In-database config settings handled by Constance" +msgstr "" + +#: templates/admin/constance/change_list.html:75 +msgid "Save" +msgstr "Guardar" + +#: templates/admin/constance/change_list.html:84 +msgid "Home" +msgstr "Inicio" + +#: templates/admin/constance/includes/results_list.html:5 +msgid "Name" +msgstr "Nombre" + +#: templates/admin/constance/includes/results_list.html:6 +msgid "Default" +msgstr "Predeterminado" + +#: templates/admin/constance/includes/results_list.html:7 +msgid "Value" +msgstr "Valor" + +#: templates/admin/constance/includes/results_list.html:8 +msgid "Is modified" +msgstr "Está modificado" + +#~ msgid "Constance config" +#~ msgstr "Configuración de Constance" diff --git a/constance/locale/et/LC_MESSAGES/django.mo b/constance/locale/et/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..4208588504deba0ef553e24b8a5914a7cd608115 GIT binary patch literal 1717 zcmca7#4?qEfq{Xafq_AWfq`KP0|SFN0|NsOBS@5iA%l^Dfs=uOA(N4TA%lT|p_q|@ zft`VY;SM7MLp}oo!xKgZ1`7rTh7cwO25trhhF&HH24w~YhM7zZ3@i)`411yUAtnZf zBnAeC<4g<;tPBhcTFeX#Yzzzx2Fwui&6yb(xEL519GMvyvKbi|e4z3>SQr?Z7#JA# zvq022u`)0;GB7asure@cGB7ZlV`X6AU|?YQ!OFlO!N9=4$Of@jiVY$z&&I%z!oa|w z!3NRa%Lei5bT)|n%c1l-HUl*IXRVj41S5Z zsSLr1WvL7y8AysV63bE*l2TLi;HH7BDbCML&Cg3!NX;ouh5M%{H77qY1ssHF`9--3 ziFqjsMXAN5Nx7LN3YGb#MGDCoiFxU%#d-{3pjcsm_ya^iV>1~Ruf+@jMfq8&$tAj; zDY{{)Ma7x*A>3;cw;ZsU79-=gQ@iSX`nTQk0lioRe6RUu31=7V6`p;OFS;s$k>l>*(p@ z;OOEK);N$4$9tv`@jgOB*PNrUdQ9446l>(Qqr>`r* ze};MnT+aDEOx*?SXsa6UlsTC#q1v!bCdDfu7D=JPcu?-Dz)3rdT134=#wMf@B zFF8LYGcVmr!6GTMgexGYv?wu0*Db#&x7bP{uK>&~wl%U=fG}+}@)Q(p6$~}4xfp^| z6H`)Ckn&P$rb0=6YDuC(F-WEalpInL6-o~8IlQMJ6D|M1)s!7xa(GEmNojGWouGmA4B;4F|rh`9;{ zsfkGn`8lb%i3(+j#U+Vl5W5v1`75=gC==qwq|6*pssy<~0qzKh8$eEg*@0wo+2JMV zj$!c0Pt`9@%qau;0hE?=Q)D##60FW&B>i_@% literal 0 HcmV?d00001 diff --git a/constance/locale/et/LC_MESSAGES/django.po b/constance/locale/et/LC_MESSAGES/django.po new file mode 100644 index 0000000..723bec9 --- /dev/null +++ b/constance/locale/et/LC_MESSAGES/django.po @@ -0,0 +1,99 @@ +# 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 , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-06-13 19:40+0530\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: admin.py:113 +#, python-format +msgid "" +"Default value type must be equal to declared config parameter type. Please " +"fix the default value of '%(name)s'." +msgstr "" +"Vaikimisi väärtus peab olema vastav seade parameetri tüübile. Palun " +"sisestagekorrekne vaikimisi väärtus väljale '%(name)s'" + +#: admin.py:123 +#, python-format +msgid "" +"Constance doesn't support config values of the type %(config_type)s. Please " +"fix the value of '%(name)s'." +msgstr "" +"Constance ei toeta seadete seda tüüpi %(config_type) seadete väärtusi. " +"Palunsisestage korrektne väärtus väljale '%(name)s'." + +#: admin.py:147 +msgid "" +"The settings have been modified by someone else. Please reload the form and " +"resubmit your changes." +msgstr "" +"Seadeid on vahepeal muudetud, palun esitage oma muudatused peale seda kui " +"olete lehe uuesti laadinud" + +#: admin.py:160 +msgid "" +"CONSTANCE_CONFIG_FIELDSETS does not contain fields that exist in " +"CONSTANCE_CONFIG." +msgstr "" + +#: admin.py:224 +msgid "Live settings updated successfully." +msgstr "Seaded edukalt muudetud." + +#: admin.py:285 +msgid "config" +msgstr "konfiguratsioon" + +#: apps.py:8 +msgid "Constance" +msgstr "Seaded" + +#: backends/database/models.py:19 +msgid "constance" +msgstr "seaded" + +#: backends/database/models.py:20 +msgid "constances" +msgstr "seaded" + +#: management/commands/constance.py:30 +msgid "Get/Set In-database config settings handled by Constance" +msgstr "Loe/salvesta andmebaasi põhiseid seadeid" + +#: templates/admin/constance/change_list.html:75 +msgid "Save" +msgstr "Salvesta" + +#: templates/admin/constance/change_list.html:84 +msgid "Home" +msgstr "" + +#: templates/admin/constance/includes/results_list.html:5 +msgid "Name" +msgstr "Nimi" + +#: templates/admin/constance/includes/results_list.html:6 +msgid "Default" +msgstr "Vaikimisi" + +#: templates/admin/constance/includes/results_list.html:7 +msgid "Value" +msgstr "Väärtus" + +#: templates/admin/constance/includes/results_list.html:8 +msgid "Is modified" +msgstr "Muudetud" diff --git a/constance/locale/fr/LC_MESSAGES/django.mo b/constance/locale/fr/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..116e58e52e5da05ae357b5b54270d19764dd3015 GIT binary patch literal 1872 zcmca7#4?qEfq_AQfq_AWfq`KT0|SFNh|LHRWnidaWMJTAU|^_ZWMIf(U|?uwWME)t zU|@K|$iR@#z`*c@k%7U2fq@}~iGhKIfq`Kz69WS`0|Ub%CI$v&1_p+8Q1MGp`Z^N> zLlOf6!yP6D237_J276`(1~vu;23KZ?JwD6~3|tHh3}MU+3^|Mp42e+jb1V!Dtqcqd zH&`I{$FVXn%wS+(NMmJSh+$x0_|FP4FNTeQfro*CA&HHFL6w1lA)k$bfti7UVJaKM zT{GDj7}^;a7?!d@?A2w5&?f8<`>oj__Peq(Fo1#pWEKYl#0*e~FflMN@PZf&5c5Dx zQ26kJ7|?J8g#*YBd<+n?p;BP~g4m$&V{p#TD=taQOHM_w6jJh2i}Tb=6pBj=3i69e z6q57v(lXN($`W%*Q;QYy(-cZFQWZ)n3sMzSH6U{FAf9Hio)yso66u>tdN_Zl9`s7n!@0dS(b{>Q(BOcSdyBeP+Xdv zoLXF*R+^JjsmI`#n48KFoLH915R!qUI3uwvRUs)gH4knY$gbl2+|>NMRE5->;#9b& zic)j(6H~z9n3i9ZtB{zNqEM7tT$+@dS)x#xUs|M)oROH9o?5KO5C)1G28d@s6f{bc zVUb(R5Kxq#m6}|l>zSe(mReMtnV)B+z!j7VieFvd;`GcEU8mCYV%?B@D+R6q{}5g0 zqSVBa%=|oEm&B4(D+MD1LvvjNb6o=?1w%_K14C^CLjwb@0Ds+})Ur&FY3S;V6%386 zj7=fxd=iUGbVG^~^NMp4OY)1X6r74m^YRrOb8-?DY!Y*F67`Zm0{IT8VxPVp1!UKcN^*%a5?Aam89mC=!R4lq*^JIq*j#Z7vv;n=2?RR zrKmWy#5Od9i$tQnwV>)z!jnEo|>0h1o2Qnerif)iGq=yfu0c;A}b+S z3VEpt1x2ZODGCLN#R{o;U}vVMD&(XVgHmg1X;HC4N-8v&mllD;ULmCvoXjz^Sy*am zW=>9Ol|piUQBh`kYLP-tBGed=DUTXv!1CLphM9T{E{9j9C6<;j_&~F5N-C22g2W<) z6o>+al>E#Rg~O{#ia-ui$UVF&H&vmq6wCqTaF9AsemuNVAtf=d7-R?}%|RWkr-094 zC>EunWKI91lGMD+B7KlMGV?Nvz`+8}>xWmA6s2Mdnp6dF22M#;NXgI3JG?TrSRwuJ z$|5iWWD_F$dgi61Rxr30mq4@J;gt*lpkf4SbZ%y`!r=u9S)dG+SeBX$&c}yW6zehg z<>xZE<`t!;XBL+fr4}*xq!ue6J1Re~MB(ttlEW+E27~26A(m5Es$QC>kfNSgT2hpX z6fQ-HX+?>d$r)fjDuD8JX-;BhQK~{}i9&IHX>Mu>DDYEK74q^+%Tg0d70U8q1y3?K VQ9yEgYH1NDpQmM}gDA}G4geVCF#!Mo literal 0 HcmV?d00001 diff --git a/constance/locale/fr/LC_MESSAGES/django.po b/constance/locale/fr/LC_MESSAGES/django.po new file mode 100644 index 0000000..44cc39c --- /dev/null +++ b/constance/locale/fr/LC_MESSAGES/django.po @@ -0,0 +1,95 @@ +# 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 , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-07-02 19:01+0100\n" +"PO-Revision-Date: 2017-07-03 12:35+0100\n" +"Last-Translator: Bruno Alla \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"Language-Team: \n" +"X-Generator: Poedit 2.0.2\n" + +#: admin.py:111 +#, python-format +msgid "" +"Default value type must be equal to declared config parameter type. Please " +"fix the default value of '%(name)s'." +msgstr "" +"Le type de la valeur par défaut doit être le même que le type déclaré dans " +"la configuration. Veuillez corriger la valeur par défaut de '%(name)s'." + +#: admin.py:121 +#, python-format +msgid "" +"Constance doesn't support config values of the type %(config_type)s. Please " +"fix the value of '%(name)s'." +msgstr "" +"Constance ne prend pas en charge les valeurs de configuration du type " +"%(config_type)s. Veuillez corriger la valeur de ‘%(name)s’." + +#: admin.py:145 +msgid "" +"The settings have been modified by someone else. Please reload the form and " +"resubmit your changes." +msgstr "" +"Les paramètres ont été modifiés par quelqu'un d'autre. Veuillez rafraichir " +"le formulaire et soumettre de nouveau vos modifications." + +#: admin.py:209 +msgid "Live settings updated successfully." +msgstr "Paramètres mis à jour avec succès." + +#: admin.py:271 +msgid "config" +msgstr "config" + +#: apps.py:8 +msgid "Constance" +msgstr "Constance" + +#: backends/database/models.py:19 +msgid "constance" +msgstr "constance" + +#: backends/database/models.py:20 +msgid "constances" +msgstr "constances" + +#: management/commands/constance.py:30 +msgid "Get/Set In-database config settings handled by Constance" +msgstr "" +"Obtenir/définir les paramètres de configuration de base de données gérées " +"par Constance" + +#: templates/admin/constance/change_list.html:68 +msgid "Save" +msgstr "Enregistrer" + +#: templates/admin/constance/change_list.html:77 +msgid "Home" +msgstr "Index" + +#: templates/admin/constance/includes/results_list.html:5 +msgid "Name" +msgstr "Nom" + +#: templates/admin/constance/includes/results_list.html:6 +msgid "Default" +msgstr "Défaut" + +#: templates/admin/constance/includes/results_list.html:7 +msgid "Value" +msgstr "Valeur" + +#: templates/admin/constance/includes/results_list.html:8 +msgid "Is modified" +msgstr "Est modifié" diff --git a/constance/locale/it/LC_MESSAGES/django.mo b/constance/locale/it/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..d621d3ba2f0c185c8d187fd528d1bb0a803d377a GIT binary patch literal 1879 zcmca7#4?qEfq_AQfq_AWfq`KT0|SFNh|LHRWnidaWMBwlU|^_ZWMJTAU|=}I$iR@n zz`$^gk%57ofq}uEiGd-Xfq}uDiGhKIfq`K=69WS`0|UbzCI$v&1_p)`Q1LfV`Xdtq zLlOf6!#5@d237_JhDc@x1~vu;hInR(`Dx4y3|tHh3pi;aQ7nt_3#lnvspjcgG6wy`lVWP#kr z22roh&cMLOz`&r#4l&;rN_(+0Fo1#pWG4p$#0*e~Ff%YP@PZf&5PyQ0pm5=5U|?W^ zh9k&dAU}Z21iWN#S5=#_PD>92q6f*M^&<)UIaL&&wE=kNwPDQZ5X631u zC={0#6yz6yjZDi-S13!&DNQX_$WK!!$w*ZwsVqoUP}NAz&r8cpj|cHIi}e%&a#9nE zQx(!OE5M4tT0lC~RWM{5w=B6?PCzho$gk&Ho z&PXgvRY*!r&4Zh!kW{HqoS&PTpO>nTnp2z#cUw_vPJUtvI5^Vsi*gkb^HLOwQj1HI zax+U5D)UQ=6p}L%^U_m`^%%lHA zSt+DsCFZ5)>%vuW1*L+bP1m6%6QoJkC9x#cO2Np$ z&_dV1Sl7^4!O+yo$V}V7(7=GpC$YFhH>4;ruQ(^MB)`Z?As{h7CttxgH77YEGry=P zRl%kJB;t?@7tzZvO1I1UScYr>7TQphaf^7Zs}MR?y(&w$H0Kd&S; zuS7SbvLMw;p(M4UM86;>F*DB^6t+dhsU^0dA#S=B2z4N5q@@<=y5=S4r)1`(TPav1 zWtMOS5eX zOB9Us4D?L6@MY7y{5()nF3C*IOI1it%q_@NNX|%ANG;ARF3Hc!$DT($a|`l|OA@Ox z^Yb#1vMI`qC!DpdS+gt zLaIV$URh?MLSAWp8N?EWoK%I9(o|@1kerbU&dvEnsi1tEmYH5!1dTtW=t*Tj;$$)a E0LhFcCjbBd literal 0 HcmV?d00001 diff --git a/constance/locale/it/LC_MESSAGES/django.po b/constance/locale/it/LC_MESSAGES/django.po new file mode 100644 index 0000000..97e5d97 --- /dev/null +++ b/constance/locale/it/LC_MESSAGES/django.po @@ -0,0 +1,105 @@ +# 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: 2017-06-13 19:40+0530\n" +"PO-Revision-Date: 2018-03-13 15:26+0100\n" +"Last-Translator: Paolo Melchiorre \n" +"Language-Team: Italian (http://www.transifex.com/projects/p/django-constance/" +"language/it/)\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 2.0.4\n" + +#: admin.py:113 +#, python-format +msgid "" +"Default value type must be equal to declared config parameter type. Please " +"fix the default value of '%(name)s'." +msgstr "" +"Il tipo dei valori di default deve essere uguale al tipo del parametro. " +"Modifica il valore di default di '%(name)s'." + +#: admin.py:123 +#, python-format +msgid "" +"Constance doesn't support config values of the type %(config_type)s. Please " +"fix the value of '%(name)s'." +msgstr "" +"Constance non supporta valori di impostazioni di tipo %(config_type)s. " +"Modifica il valore di '%(name)s'." + +#: admin.py:147 +msgid "" +"The settings have been modified by someone else. Please reload the form and " +"resubmit your changes." +msgstr "" +"Le impostazioni sono state modificate da qualcuno. Ricarica la pagina e " +"invia nuovamente le tue modifiche." + +#: admin.py:160 +msgid "" +"CONSTANCE_CONFIG_FIELDSETS does not contain fields that exist in " +"CONSTANCE_CONFIG." +msgstr "" +"CONSTANCE_CONFIG_FIELDSETS non contiene campi che esistono in " +"CONSTANCE_CONFIG." + +#: admin.py:224 +msgid "Live settings updated successfully." +msgstr "Le impostazioni attive sono state aggiornate correttamente." + +#: admin.py:285 +msgid "config" +msgstr "configurazioni" + +#: apps.py:8 +msgid "Constance" +msgstr "Impostazioni" + +#: backends/database/models.py:19 +msgid "constance" +msgstr "impostazione" + +#: backends/database/models.py:20 +msgid "constances" +msgstr "impostazioni" + +#: management/commands/constance.py:30 +msgid "Get/Set In-database config settings handled by Constance" +msgstr "" + +#: templates/admin/constance/change_list.html:75 +msgid "Save" +msgstr "Salva" + +#: templates/admin/constance/change_list.html:84 +msgid "Home" +msgstr "Inizio" + +#: templates/admin/constance/includes/results_list.html:5 +msgid "Name" +msgstr "Nome" + +#: templates/admin/constance/includes/results_list.html:6 +msgid "Default" +msgstr "Default" + +#: templates/admin/constance/includes/results_list.html:7 +msgid "Value" +msgstr "Valore" + +#: templates/admin/constance/includes/results_list.html:8 +msgid "Is modified" +msgstr "Modificato" + +#~ msgid "Constance config" +#~ msgstr "Configurazione Impostazioni" diff --git a/constance/locale/pl/LC_MESSAGES/django.mo b/constance/locale/pl/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..3f7e0f82263bca0af4871479407d2d08aa317c24 GIT binary patch literal 1010 zcmca7#4?qEfq{XWfq_AWfq|iffq_Agfq~%+NRWYnL4c8gK>#Gi$iTqPz`&ry$iTqD zz`&rz2+^a@$iSe?z`$S)6_1C~DU1vZtPBhcnT!k!oD2*M`HTzp{zc4dE%w%GKxB(>3;GCaVT#}fV zoT`wVpO==I&ft=omROoo!r+mgo66u>tdN_Zl9`s7n!@0dS(d6$oLW+nnU`LyP+E|Z zSdyBeP+XdvoLXF*R+^JjsmI`#n48KFoLH915SExzn#zz2GabPyW(X+C&q_@$(e+Hx z4NEO5&dkrVQb@^4%uCPLg{$WZN-fAQD$(^VPR~rybt+9S)(y$GQs4^k57BilN=+=u z%+J$xNi0dVQZO6jLFMxQsSie9Y-Jkk7 zP_y(4a`ZL1d_8?#5rJZ;XTas0pI4HaSE3tIS&(X_P?B0vqF<1cn3-p-kercNRGeC3 z8ye!KYk^P)vNhe)yT88HB_)yFi@~k$Wt{mu(LH%P*VdlZEQ_IObw8*fsLVoLQM@=9HhoT zQ^8)rP{B&UNYk2&!5f^QN{bScvl12H>5Rc8KezJe?3}#JREB{3nyI6N^gnkIp{Q&QJi=2xn9>007n_2m$~A literal 0 HcmV?d00001 diff --git a/constance/locale/pl/LC_MESSAGES/django.po b/constance/locale/pl/LC_MESSAGES/django.po new file mode 100644 index 0000000..47348bb --- /dev/null +++ b/constance/locale/pl/LC_MESSAGES/django.po @@ -0,0 +1,97 @@ +# 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: 2017-06-13 19:40+0530\n" +"PO-Revision-Date: 2014-11-27 18:13+0000\n" +"Last-Translator: Jannis Leidel \n" +"Language-Team: Polish (http://www.transifex.com/projects/p/django-constance/" +"language/pl/)\n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\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:113 +#, python-format +msgid "" +"Default value type must be equal to declared config parameter type. Please " +"fix the default value of '%(name)s'." +msgstr "" + +#: admin.py:123 +#, 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:147 +msgid "" +"The settings have been modified by someone else. Please reload the form and " +"resubmit your changes." +msgstr "" + +#: admin.py:160 +msgid "" +"CONSTANCE_CONFIG_FIELDSETS does not contain fields that exist in " +"CONSTANCE_CONFIG." +msgstr "" + +#: admin.py:224 +msgid "Live settings updated successfully." +msgstr "Parametry zostały zaktualizowane" + +#: admin.py:285 +msgid "config" +msgstr "" + +#: apps.py:8 +msgid "Constance" +msgstr "" + +#: backends/database/models.py:19 +msgid "constance" +msgstr "parametr" + +#: backends/database/models.py:20 +msgid "constances" +msgstr "parametry" + +#: management/commands/constance.py:30 +msgid "Get/Set In-database config settings handled by Constance" +msgstr "" + +#: templates/admin/constance/change_list.html:75 +msgid "Save" +msgstr "Zapisz" + +#: templates/admin/constance/change_list.html:84 +msgid "Home" +msgstr "Początek" + +#: templates/admin/constance/includes/results_list.html:5 +msgid "Name" +msgstr "Nazwa" + +#: templates/admin/constance/includes/results_list.html:6 +msgid "Default" +msgstr "Domyślnie" + +#: templates/admin/constance/includes/results_list.html:7 +msgid "Value" +msgstr "Wartość" + +#: templates/admin/constance/includes/results_list.html:8 +msgid "Is modified" +msgstr "Zmodyfikowana" + +#~ msgid "Constance config" +#~ msgstr "Konfiguracja Constance" diff --git a/constance/locale/ru/LC_MESSAGES/django.mo b/constance/locale/ru/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..c749d6882912fbb8671876909ecefb5b09e815a1 GIT binary patch literal 1126 zcmca7#4?qEfq{XWfq_AWfq|iffq_Agfq~%+NRWYnL4c8gfgL2q$iTqDz`!8M2vIA? z$iSe?z`&pd759VE!Hf(HtPBhc5sVBBYzzzxaf}QMoD2*Msf-K^Tnr2h`HTz>xgG*{! zVrfnZgGYXDDuZXSLT-LaW?E)y3WHB(S*k*DYDr0EUV5=YX+cV2NotBhacOdLYH@K| zX--b19)n+EZYo1?Vp%FfSYl3TDnoL9URq{4h$=2g%u5CfKv=~L0Y&*)smUd}o+-Lv zsYS(^`FU0fDOrhm>G`_J`FRjkTtTS?`9&qVzQyU8DY{Oj>BYJs`Bn;C0sbMn&PAz- zC7Jnox-N+&sa6U`28QOk24=d3#tMd(Rwf482ByXaTmk;NL8)b#Akz`*Omqzmb&bpw z3@xk-jkOI73=Ft@5{pZ8Ly8jfigOZ6@{6n#yb|;BGK&>_QZrLha};c{z+8tMFjp@# zFD>7W%O^1}y)-dBRW~FxG1p2VsI<5^Gciv=Bcr6Gz)D}gyu4hm1Y}}nT55$}a(=FU z0mR3}`UU#v9@Wo*8m3=Vs;>z*+Df6Ql*`xC*A)>&hI$5E&iQ#Isd**3A(aKGRthDl z6(#xwIf{Gbdd|}UpeHV6LY`?JK z!rluzF7`28n0#UPg$)-rUD$hJ!^M7v3llGPU)X(NpTdP57q(y6b7AX+yVPJV&jGV7q(vPxUd&wdgFzC7h5kjfX&`|VeiFmu%-*! zFKhw}?YOX&;le^BH9IagUF>1Fu;{|p3%f2hU+lcF^}<$#3){g?X$M;i)&g=Fip30I H6$FI\n" +"Language-Team: Russian (http://www.transifex.com/projects/p/django-constance/" +"language/ru/)\n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\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:113 +#, python-format +msgid "" +"Default value type must be equal to declared config parameter type. Please " +"fix the default value of '%(name)s'." +msgstr "" + +#: admin.py:123 +#, 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:147 +msgid "" +"The settings have been modified by someone else. Please reload the form and " +"resubmit your changes." +msgstr "" + +#: admin.py:160 +msgid "" +"CONSTANCE_CONFIG_FIELDSETS does not contain fields that exist in " +"CONSTANCE_CONFIG." +msgstr "" + +#: admin.py:224 +msgid "Live settings updated successfully." +msgstr "Настройки успешно сохранены" + +#: admin.py:285 +msgid "config" +msgstr "настройки" + +#: apps.py:8 +msgid "Constance" +msgstr "" + +#: backends/database/models.py:19 +msgid "constance" +msgstr "настройки" + +#: backends/database/models.py:20 +msgid "constances" +msgstr "настройки" + +#: management/commands/constance.py:30 +msgid "Get/Set In-database config settings handled by Constance" +msgstr "" + +#: templates/admin/constance/change_list.html:75 +msgid "Save" +msgstr "Сохранить" + +#: templates/admin/constance/change_list.html:84 +msgid "Home" +msgstr "Главная" + +#: templates/admin/constance/includes/results_list.html:5 +msgid "Name" +msgstr "Название" + +#: templates/admin/constance/includes/results_list.html:6 +msgid "Default" +msgstr "По умолчанию" + +#: templates/admin/constance/includes/results_list.html:7 +msgid "Value" +msgstr "Текущее значение" + +#: templates/admin/constance/includes/results_list.html:8 +msgid "Is modified" +msgstr "Было изменено" + +#~ msgid "Constance config" +#~ msgstr "Настройки" diff --git a/constance/locale/zh_CN/LC_MESSAGES/django.mo b/constance/locale/zh_CN/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..2f73cb13942a9ecf11014d188e13be78ed931a60 GIT binary patch literal 1368 zcmca7#4?qEfq{XKfq_AWfq|iifq_Aofq~%3fs=uO!IP1JA%lT|A()YY zft`VYVGkn%0}BHK!x2UX25trhhLem849W})3|FDzKcVzLMh1o?1_lOZCI$vp1_p*S zCI$vJ1_p*4CWyJkObiTM3=9mlObiSw85tNlm>3xN85kIhSQr?B85kIxSRm@Au|V`K zV1dXlXJKHFU|?X_4i&!urLVIvF!(VrFx+EdU|?ooV9;fS=rd%6=(B**9;^%uj8K2` zLjB6Y0P!1$3vw$H1H^40|AG7pG7l6MAbF4EtLrhiq^2d7=9DmaVIUtfK)eW|pdpnE3$tQ|fTH}Y)Z`Lf&lKIT)S}|d{5&g#l&r+O z^n6{oDz2bZP%!HH7N=*X=sK0A7wd-PTPbh__=o5^7o{eaWaj7Tx+IpQS}7PA7@F%E znCTiCD;Qc@nHXprm>L^!1^DX*rIuxaOh>3Q)ip5IH8fQ)v;eC!FficqNh~hW4Jk^@ zE6zzQ$uF`}h|EkYRfsHAuqn#VFLB69OwO*XOw&uw&$Z+7Nz6+xO-xVK4M|PRwNh}- z$jnPEPF2tVF%mTuG%`v`3as??%gf94N7#p6KL=`{epN=i zv!A{u+y*NJun3p0r>`p_kPP(cMmbVDi&Qmqt9QY%XI3vv=O^Q=KJP*j{+ zVjCLbrfY#v2XaVSYLTvMUUGg)W?s6Lf<;nh30FW)X;EU1u3LUlZn2d@UICa}Y-?z( z0Abo1SaTtg_p=oXpU$0*;6K^X`)tbkXFZKi_RoE~cE6TopYUYYl4ngT Zp3iCl*)nA($XQ?qLF|ENa`aGu@&O{v%R2x7 literal 0 HcmV?d00001 diff --git a/constance/locale/zh_CN/LC_MESSAGES/django.po b/constance/locale/zh_CN/LC_MESSAGES/django.po new file mode 100644 index 0000000..2fa88bc --- /dev/null +++ b/constance/locale/zh_CN/LC_MESSAGES/django.po @@ -0,0 +1,100 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Yifu Yu , 2015 +msgid "" +msgstr "" +"Project-Id-Version: django-constance\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-06-13 19:40+0530\n" +"PO-Revision-Date: 2015-03-15 18:40+0000\n" +"Last-Translator: Yifu Yu \n" +"Language-Team: Chinese (China) (http://www.transifex.com/jezdez/django-" +"constance/language/zh_CN/)\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: admin.py:113 +#, fuzzy, python-format +#| msgid "" +#| "Constance doesn't support config values of the type %(config_type)s. " +#| "Please fix the value of '%(name)s'." +msgid "" +"Default value type must be equal to declared config parameter type. Please " +"fix the default value of '%(name)s'." +msgstr "Constance不支持保存类型为%(config_type)s的值,请修正%(name)s的值。" + +#: admin.py:123 +#, python-format +msgid "" +"Constance doesn't support config values of the type %(config_type)s. Please " +"fix the value of '%(name)s'." +msgstr "Constance不支持保存类型为%(config_type)s的值,请修正%(name)s的值。" + +#: admin.py:147 +msgid "" +"The settings have been modified by someone else. Please reload the form and " +"resubmit your changes." +msgstr "设置已经被他人修改过,请刷新页面并重新提交您的更改。" + +#: admin.py:160 +msgid "" +"CONSTANCE_CONFIG_FIELDSETS does not contain fields that exist in " +"CONSTANCE_CONFIG." +msgstr "" + +#: admin.py:224 +msgid "Live settings updated successfully." +msgstr "成功更新实时配置" + +#: admin.py:285 +msgid "config" +msgstr "配置" + +#: apps.py:8 +msgid "Constance" +msgstr "Constance模块" + +#: backends/database/models.py:19 +msgid "constance" +msgstr "Constance模块" + +#: backends/database/models.py:20 +msgid "constances" +msgstr "Constance模块" + +#: management/commands/constance.py:30 +msgid "Get/Set In-database config settings handled by Constance" +msgstr "" + +#: templates/admin/constance/change_list.html:75 +msgid "Save" +msgstr "保存" + +#: templates/admin/constance/change_list.html:84 +msgid "Home" +msgstr "首页" + +#: templates/admin/constance/includes/results_list.html:5 +msgid "Name" +msgstr "名称" + +#: templates/admin/constance/includes/results_list.html:6 +msgid "Default" +msgstr "默认值" + +#: templates/admin/constance/includes/results_list.html:7 +msgid "Value" +msgstr "值" + +#: templates/admin/constance/includes/results_list.html:8 +msgid "Is modified" +msgstr "是否修改过" + +#~ msgid "Constance config" +#~ msgstr "Constance 配置页面" diff --git a/constance/locale/zh_Hans/LC_MESSAGES/django.mo b/constance/locale/zh_Hans/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..f645fbce1c933883e4ff6a389931717d42add468 GIT binary patch literal 1909 zcmca7#4?qEfq_AYfq_AWfq`KS0|SFB0|SE%BS@5iVFM!rgFgcU!$w91h71M<21X_Z z1|9|mhAbuq26hGphH@qbhI|GFhI%Fj1`7rThWAVi3@i)`3>wS~4BQM147$t=49W}) z43^9g@mOXC1_1^Jh9oGzn3;hgiGhKkf|-GVm4SibHZubQ8v_HwLuLjBP6h^s7t9O{ zTnr2hpO_gKQWzN+{xUN#c!Tt_GB5-)FfgoRg}8@_4Wgc(je#M6fq_Aije)@ukFzkkkUtxpz{Wg^Uj*WrAkAZ>VE7Uv}c8GpIc8LB^D4ojA zzyJy&K?aEXAfW~E1BlHBA{ZDLIG{9$0);V%2KkSP0TLb{J_z$NK->=sGf?<|#F!Z% zVGIgy5Fg}z24{c2;1EYYXV-XVe?K=*_jor?S09&P*N|X^%wmPy%;MtAymW=M%+#C| zjbcrOl8nR>h1817;*w&8%sd5j-Fghp`FX`9iFwJX3Mu)i#d+!_3dN-b1^GoK3d#9- zX_@H?Wr;bZsl^KUX$mD7sR|{P1*rE6_Qd@ z^WesVEHBQ_P0i0sRY=V#PKEojC^aWPF$EmTY57ID3W<3s3Pq{KrAfJ&B?^`Kr9}$K z8Hsu6sl|E>VW5a(fcOqXL82MKDrN{M%FjwoF46T&(G5#2D$dN$vr-6fboO?1cU1^; z4GQ-3_u~pm1tkVu-{SPl6kVs%^kUtRd@BX60RIqO=c3falFa-(U6;g?R4WA|149d4 z0~1|CO9ewiD`P`#0}BHKt^j}CpwzNVkl|2uk*7|M3sk$Ml ziMdt^K8}9wp&%#Q`1m;FWa{M?r6bf>DRB9E`nn?gXQ*eu<(!{alA2ed8&X-2YNb$; zT2Z23kdv61XAKIxqTRdkh9WKi*#M{lJiqC^U|#pERr%yxB_xYixP8m z-SUfai>(y$3c%cATSIFF2-DWUnhQ^ceX?Wi^F6zsZkYIV&IKHs~J;pMVvFBfiQcs67G(+SH!-k7rU#r}4N zr|afDo4yUA=Gp8m&!%m7)-mB}*L;Sj6MCO7-@x#)9i;n3`(}ivAfd$oalzB=o1X9P zf3axwlikyv?Air47~+km9owHx+wgMX)|Yb^J>9wOWqU8kg8m6lb}f0, 2015. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-04-19 11:31+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: YinKH <614457662@qq.com>\n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: .\admin.py:115 +#, python-format +msgid "" +"Default value type must be equal to declared config parameter type. Please " +"fix the default value of '%(name)s'." +msgstr "默认值的类型必须与参数声明类型相同,请修正%(name)s的值。" + +#: .\admin.py:125 +#, python-format +msgid "" +"Constance doesn't support config values of the type %(config_type)s. Please " +"fix the value of '%(name)s'." +msgstr "Constance不支持保存类型为%(config_type)s的值,请修正%(name)s的值。" + +#: .\admin.py:157 +msgid "" +"The settings have been modified by someone else. Please reload the form and " +"resubmit your changes." +msgstr "设置已经被他人修改过,请刷新页面并重新提交您的更改。" + +#: .\admin.py:173 +msgid "" +"CONSTANCE_CONFIG_FIELDSETS is missing field(s) that exists in " +"CONSTANCE_CONFIG." +msgstr "CONSTANCE_CONFIG_FIELDSETS中缺少在CONSTANCE_CONFIG中声明的字段。" + +#: .\admin.py:240 +msgid "Live settings updated successfully." +msgstr "实时配置更新成功" + +#: .\admin.py:301 +msgid "config" +msgstr "配置" + +#: .\backends\database\models.py:19 +msgid "constance" +msgstr "Constance模块" + +#: .\backends\database\models.py:20 +msgid "constances" +msgstr "Constance模块" + +#: .\management\commands\constance.py:30 +msgid "Get/Set In-database config settings handled by Constance" +msgstr "获取或设置由Constance模块处理的数据库配置" + +#: .\templates\admin\constance\change_list.html:60 +msgid "Save" +msgstr "保存" + +#: .\templates\admin\constance\change_list.html:69 +msgid "Home" +msgstr "首页" + +#: .\templates\admin\constance\includes\results_list.html:5 +msgid "Name" +msgstr "名称" + +#: .\templates\admin\constance\includes\results_list.html:6 +msgid "Default" +msgstr "默认值" + +#: .\templates\admin\constance\includes\results_list.html:7 +msgid "Value" +msgstr "当前值" + +#: .\templates\admin\constance\includes\results_list.html:8 +msgid "Is modified" +msgstr "是否修改过" + +#: .\templates\admin\constance\includes\results_list.html:21 +msgid "Current file" +msgstr "当前文件" + +#: .\templates\admin\constance\includes\results_list.html:36 +msgid "Reset to default" +msgstr "重置至默认值" diff --git a/constance/management/__init__.py b/constance/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/constance/management/commands/__init__.py b/constance/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/constance/management/commands/constance.py b/constance/management/commands/constance.py new file mode 100644 index 0000000..0fc48f2 --- /dev/null +++ b/constance/management/commands/constance.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals + +from django.core.exceptions import ValidationError +from django.core.management import BaseCommand, CommandError +from django.utils.translation import ugettext as _ +from django import VERSION + + +from ... import config +from ...admin import ConstanceForm, get_values + + +def _set_constance_value(key, value): + """ + Parses and sets a Constance value from a string + :param key: + :param value: + :return: + """ + + form = ConstanceForm(initial=get_values()) + + field = form.fields[key] + + clean_value = field.clean(field.to_python(value)) + setattr(config, key, clean_value) + + +class Command(BaseCommand): + help = _('Get/Set In-database config settings handled by Constance') + + def add_arguments(self, parser): + subparsers = parser.add_subparsers(dest='command') + # API changed in Django>=2.1. cmd argument was removed. + parser_list = self._subparsers_add_parser(subparsers, 'list', cmd=self, help='list all Constance keys and their values') + + parser_get = self._subparsers_add_parser(subparsers, 'get', cmd=self, help='get the value of a Constance key') + parser_get.add_argument('key', help='name of the key to get', metavar='KEY') + + parser_set = self._subparsers_add_parser(subparsers, 'set', cmd=self, help='set the value of a Constance key') + parser_set.add_argument('key', help='name of the key to get', metavar='KEY') + # use nargs='+' so that we pass a list to MultiValueField (eg SplitDateTimeField) + parser_set.add_argument('value', help='value to set', metavar='VALUE', nargs='+') + + + def _subparsers_add_parser(self, subparsers, name, **kwargs): + # API in Django >= 2.1 changed and removed cmd parameter from add_parser + if VERSION >= (2, 1) and 'cmd' in kwargs: + kwargs.pop('cmd') + return subparsers.add_parser(name, **kwargs) + + + def handle(self, command, key=None, value=None, *args, **options): + + if command == 'get': + try: + self.stdout.write("{}".format(getattr(config, key)), ending="\n") + except AttributeError as e: + raise CommandError(key + " is not defined in settings.CONSTANCE_CONFIG") + + elif command == 'set': + try: + if len(value) == 1: + # assume that if a single argument was passed, the field doesn't expect a list + value = value[0] + + _set_constance_value(key, value) + except KeyError as e: + raise CommandError(key + " is not defined in settings.CONSTANCE_CONFIG") + except ValidationError as e: + raise CommandError(", ".join(e)) + + elif command == 'list': + for k, v in get_values().items(): + self.stdout.write("{}\t{}".format(k, v), ending="\n") diff --git a/constance/settings.py b/constance/settings.py new file mode 100644 index 0000000..1c597e2 --- /dev/null +++ b/constance/settings.py @@ -0,0 +1,45 @@ +from django.conf import settings + +BACKEND = getattr( + settings, + 'CONSTANCE_BACKEND', + 'constance.backends.redisd.RedisBackend' +) + +CONFIG = getattr(settings, 'CONSTANCE_CONFIG', {}) + +CONFIG_FIELDSETS = getattr(settings, 'CONSTANCE_CONFIG_FIELDSETS', {}) + +ADDITIONAL_FIELDS = getattr(settings, 'CONSTANCE_ADDITIONAL_FIELDS', {}) + +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) + +IGNORE_ADMIN_VERSION_CHECK = getattr( + settings, + 'CONSTANCE_IGNORE_ADMIN_VERSION_CHECK', + False +) diff --git a/constance/signals.py b/constance/signals.py new file mode 100644 index 0000000..f0c9796 --- /dev/null +++ b/constance/signals.py @@ -0,0 +1,5 @@ +import django.dispatch + +config_updated = django.dispatch.Signal( + providing_args=['key', 'old_value', 'new_value'] +) diff --git a/constance/static/admin/css/constance.css b/constance/static/admin/css/constance.css new file mode 100644 index 0000000..4d74660 --- /dev/null +++ b/constance/static/admin/css/constance.css @@ -0,0 +1,15 @@ +#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; +} diff --git a/constance/static/admin/js/constance.js b/constance/static/admin/js/constance.js new file mode 100644 index 0000000..690dfcc --- /dev/null +++ b/constance/static/admin/js/constance.js @@ -0,0 +1,26 @@ +(function($) { + 'use strict'; + + $(function() { + + $('#content-main').on('click', '.reset-link', function(e) { + e.preventDefault(); + + var field = $('#' + this.dataset.fieldId); + var fieldType = this.dataset.fieldType; + + if (fieldType === 'checkbox') { + field.prop('checked', this.dataset.default === 'true'); + } else if (fieldType === 'date') { + var defaultDate = new Date(this.dataset.default * 1000); + $('#' + this.dataset.fieldId).val(defaultDate.strftime(get_format('DATE_INPUT_FORMATS')[0]));} + } else if (fieldType === 'datetime') { + var defaultDate = new Date(this.dataset.default * 1000); + $('#' + this.dataset.fieldId + '_0').val(defaultDate.strftime(get_format('DATE_INPUT_FORMATS')[0])); + $('#' + this.dataset.fieldId + '_1').val(defaultDate.strftime(get_format('TIME_INPUT_FORMATS')[0])); + } else { + field.val(this.dataset.default); + } + }); + }); +})(django.jQuery); diff --git a/constance/templates/admin/constance/change_list.html b/constance/templates/admin/constance/change_list.html new file mode 100644 index 0000000..bdee4d2 --- /dev/null +++ b/constance/templates/admin/constance/change_list.html @@ -0,0 +1,73 @@ +{% extends "admin/base_site.html" %} +{% load admin_static admin_list i18n %} + +{% block extrastyle %} + {{ block.super }} + + + {{ media.css }} + +{% endblock %} + +{% block extrahead %} +{% url 'admin:jsi18n' as jsi18nurl %} + +{{ block.super }} +{{ media.js }} + +{% endblock %} + +{% block bodyclass %}change-list{% endblock %} + +{% block content %} +
+
+
{% csrf_token %} + {% if form.non_field_errors %} +
    + {% for error in form.non_field_errors %} +
  • {{ error }}
  • + {% endfor %} +
+ {% endif %} + {% if form.errors %} +
    + {% endif %} + {% for field in form.hidden_fields %} + {% for error in field.errors %} +
  • {{ error }}
  • + {% endfor %} + {{ field }} + {% endfor %} + {% if form.errors %} +
+ {% endif %} + + {% if fieldsets %} + {% for fieldset in fieldsets %} +
+

{{ fieldset.title }}

+ {% with config_values=fieldset.config_values %} + {% include "admin/constance/includes/../../../../venv/Lib/site-packages/constance/templates/admin/constance/includes/results_list.html" %} + {% endwith %} +
+ {% endfor %} + {% else %} + {% include "admin/constance/includes/../../../../venv/Lib/site-packages/constance/templates/admin/constance/includes/results_list.html" %} + {% endif %} + +

+ +

+
+
+
+{% endblock %} + +{% block breadcrumbs %} + +{% endblock %} diff --git a/constance/templates/admin/constance/includes/results_list.html b/constance/templates/admin/constance/includes/results_list.html new file mode 100644 index 0000000..295388b --- /dev/null +++ b/constance/templates/admin/constance/includes/results_list.html @@ -0,0 +1,49 @@ +{% load admin_static admin_list static i18n %} + + + + + + + + + + {% for item in config_values %} + + + + + + + {% endfor %} +
{% trans "Name" %}
{% trans "Default" %}
{% trans "Value" %}
{% trans "Is modified" %}
+ {{ item.name }}
{{ item.help_text|linebreaksbr }}
+
+ {{ item.default|linebreaks }} + + {{ item.form_field.errors }} + {% if item.is_file %}{% trans "Current file" %}: {{ item.value }}{% endif %} + {{ item.form_field }} +
+ {% trans "Reset to default" %} +
+ {% if item.modified %} + {{ item.modified }} + {% else %} + {{ item.modified }} + {% endif %} +
diff --git a/constance/test/__init__.py b/constance/test/__init__.py new file mode 100644 index 0000000..0fb5524 --- /dev/null +++ b/constance/test/__init__.py @@ -0,0 +1 @@ +from .utils import override_config diff --git a/constance/test/utils.py b/constance/test/utils.py new file mode 100644 index 0000000..eff0abd --- /dev/null +++ b/constance/test/utils.py @@ -0,0 +1,85 @@ +from functools import wraps + +from django.test import SimpleTestCase +from django.test.utils import override_settings + +from .. import config + +__all__ = ('override_config',) + + +class override_config(override_settings): + """ + Decorator to modify constance setting for TestCase. + + Based on django.test.utils.override_settings. + """ + def __init__(self, **kwargs): + super(override_config, self).__init__(**kwargs) + self.original_values = {} + + def __call__(self, test_func): + """ + Modify the decorated function to override config values. + """ + if isinstance(test_func, type): + if not issubclass(test_func, SimpleTestCase): + raise Exception( + "Only subclasses of Django SimpleTestCase can be " + "decorated with override_config") + return self.modify_test_case(test_func) + else: + @wraps(test_func) + def inner(*args, **kwargs): + with self: + return test_func(*args, **kwargs) + return inner + + def modify_test_case(self, test_case): + """ + Override the config by modifying TestCase methods. + + This method follows the Django <= 1.6 method of overriding the + _pre_setup and _post_teardown hooks rather than modifying the TestCase + itself. + """ + original_pre_setup = test_case._pre_setup + original_post_teardown = test_case._post_teardown + + def _pre_setup(inner_self): + self.enable() + original_pre_setup(inner_self) + + def _post_teardown(inner_self): + original_post_teardown(inner_self) + self.disable() + + test_case._pre_setup = _pre_setup + test_case._post_teardown = _post_teardown + + return test_case + + def enable(self): + """ + Store original config values and set overridden values. + """ + # Store the original values to an instance variable + for config_key in self.options: + self.original_values[config_key] = getattr(config, config_key) + + # Update config with the overriden values + self.unpack_values(self.options) + + def disable(self): + """ + Set original values to the config. + """ + self.unpack_values(self.original_values) + + @staticmethod + def unpack_values(options): + """ + Unpack values from the given dict to config. + """ + for name, value in options.items(): + setattr(config, name, value) diff --git a/constance/utils.py b/constance/utils.py new file mode 100644 index 0000000..8d8d341 --- /dev/null +++ b/constance/utils.py @@ -0,0 +1,6 @@ +from importlib import import_module + + +def import_module_attr(path): + package, module = path.rsplit('.', 1) + return getattr(import_module(package), module) diff --git a/requirements.txt b/requirements.txt index a6d4ac4..b2ffc6f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ -Django>=1.10,<2.1 ; python_version >= '3.4' +Django>=1.10; python_version >= '3.4' Pillow>=2.9.0 apscheduler>=3.3.0 -django-constance[database]>=2.1 +#django-constance[database]>=2.1 lxml python-telegram-bot>=10 -- GitLab