Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions dbsettings/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
re_field_name = re.compile(r'^(.+)__(.*)__(.+)$')

class SettingsEditor(forms.BaseForm):
"Base editor, from which customized forms are created"
"""Base editor, from which customized forms are created"""

def __iter__(self):
for field in super(SettingsEditor, self).__iter__():
Expand All @@ -20,7 +20,7 @@ def __getitem__(self, name):
return self.specialize(field)

def specialize(self, field):
"Wrapper to add module_name and class_name for regrouping"
"""Wrapper to add module_name and class_name for regrouping"""
field.label = capfirst(field.label)
module_name, class_name, x = re_field_name.match(field.name).groups()

Expand All @@ -36,21 +36,23 @@ def specialize(self, field):
return field

def customized_editor(user, settings):
"Customize the setting editor based on the current user and setting list"
"""Customize the setting editor based on the current user and setting list"""
base_fields = SortedDict()
for setting in settings:
perm = '%s.can_edit_%s_settings' % (
setting.module_name.split('.')[-2],
setting.class_name.lower()
)
if user.has_perm(perm):
# dbsettings.change_setting permission overrides any/all dbsettings group-specific perms
if user.has_perm(perm) or user.has_perm("dbsettings.change_setting"):
# Add the field to the customized field list
storage = get_setting_storage(*setting.key)
kwargs = {
'label': setting.description,
'help_text': setting.help_text,
# Provide current setting values for initializing the form
'initial': setting.to_editor(storage.value),
'required': setting.required,
}
if setting.choices:
field = forms.ChoiceField(choices=setting.choices, **kwargs)
Expand Down
4 changes: 3 additions & 1 deletion dbsettings/loading.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
'register_setting', 'set_setting_value']

class SettingDict(SortedDict):
"Sorted dict that has a bit more list-type functionality"
"""Sorted dict that has a bit more list-type functionality"""

def __iter__(self):
return self.itervalues()
Expand Down Expand Up @@ -39,10 +39,12 @@ def get_setting_storage(module_name, class_name, attribute_name):
attribute_name=attribute_name,
)
except Setting.DoesNotExist:
setting_object = get_setting(module_name, class_name, attribute_name)
storage = Setting(
module_name=module_name,
class_name=class_name,
attribute_name=attribute_name,
value=setting_object.default,
)
cache.set(key, storage)
return storage
Expand Down
2 changes: 1 addition & 1 deletion dbsettings/templates/dbsettings/app_settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@


{% block coltype %}colMS{% endblock %}
{% block bodyclass %}dashboard{% endblock %}
{% block bodyclass %}dbsettings{% endblock %}
{% block userlinks %}<a href="/admin/doc/">{% trans 'Documentation' %}</a> / <a href="/admin/password_change/">{% trans 'Change password' %}</a> / <a href="/admin/logout/">{% trans 'Log out' %}</a>{% endblock %}
{% block breadcrumbs %}{% if not is_popup %}
<div class="breadcrumbs">
Expand Down
2 changes: 1 addition & 1 deletion dbsettings/templates/dbsettings/site_settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/forms.css" />{% endblock %}

{% block coltype %}colMS{% endblock %}
{% block bodyclass %}dashboard{% endblock %}
{% block bodyclass %}dbsettings{% endblock %}
{% block userlinks %}<a href="/admin/doc/">{% trans 'Documentation' %}</a> / <a href="/admin/password_change/">{% trans 'Change password' %}</a> / <a href="/admin/logout/">{% trans 'Log out' %}</a>{% endblock %}
{% block breadcrumbs %}{% if not is_popup %}
<div class="breadcrumbs">
Expand Down
39 changes: 38 additions & 1 deletion dbsettings/tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ class TestSettings(dbsettings.Group):
# This is assigned to module, rather than a model
module_settings = TestSettings()

class Defaults(models.Model):
class settings(dbsettings.Group):
boolean = dbsettings.BooleanValue(default=True)
boolean_false = dbsettings.BooleanValue(default=False)
integer = dbsettings.IntegerValue(default=1)
string = dbsettings.StringValue(default="default")
list_semi_colon = dbsettings.MultiSeparatorValue(default=['one','two'])
list_comma = dbsettings.MultiSeparatorValue(separator=',',default=('one','two'))
settings = settings()

# These will be populated by the fixture data
class Populated(models.Model):
settings = TestSettings()
Expand All @@ -24,6 +34,10 @@ class Populated(models.Model):
class Unpopulated(models.Model):
settings = TestSettings()

# These will allow blank values
class Blankable(models.Model):
settings = TestSettings()

class Editable(models.Model):
settings = TestSettings()

Expand Down Expand Up @@ -87,6 +101,15 @@ def test_settings(self):
self.assertEqual(Unpopulated.settings.list_semi_colon, [])
self.assertEqual(Unpopulated.settings.list_comma, [])

# ...Unless a default paramter was specified, then they use that
self.assertEqual(Defaults.settings.boolean, True)
self.assertEqual(Defaults.settings.boolean_false, False)
self.assertEqual(Defaults.settings.integer, 1)
self.assertEqual(Defaults.settings.string, 'default')
self.assertEqual(Defaults.settings.list_semi_colon, ['one','two'])
self.assertEqual(Defaults.settings.list_comma, ['one','two'])


# Settings should be retrieved in the order of definition
self.assertEqual(Populated.settings.keys(),
['boolean', 'integer', 'string', 'list_semi_colon',
Expand Down Expand Up @@ -116,6 +139,20 @@ def test_settings(self):
self.assertEqual(Unpopulated.settings.list_semi_colon, ['[email protected]', '[email protected]'])
self.assertEqual(Unpopulated.settings.list_comma, ['[email protected]', '[email protected]'])

# Updating settings with defaults
loading.set_setting_value('dbsettings.tests.tests', 'Defaults', 'boolean', False)
self.assertEqual(Defaults.settings.boolean, False)
loading.set_setting_value('dbsettings.tests.tests', 'Defaults', 'boolean_false', True)
self.assertEqual(Defaults.settings.boolean_false, True)


# Updating blankable settings
self.assertEqual(Blankable.settings.string, '')
loading.set_setting_value('dbsettings.tests.tests', 'Blankable', 'string', 'Eli')
self.assertEqual(Blankable.settings.string, 'Eli')
loading.set_setting_value('dbsettings.tests.tests', 'Blankable', 'string', '')
self.assertEqual(Blankable.settings.string, '')

# And they can be modified in-place
Unpopulated.settings.boolean = False
Unpopulated.settings.integer = 42
Expand All @@ -127,7 +164,7 @@ def test_settings(self):
self.assertEqual(Unpopulated.settings.integer, 42)
self.assertEqual(Unpopulated.settings.string, 'Caturday')
self.assertEqual(Unpopulated.settings.list_semi_colon, ['[email protected]', '[email protected]'])
self.assertEqual(Unpopulated.settings.list_comma, ['[email protected]', '[email protected]'])
self.assertEqual(Unpopulated.settings.list_comma, ['[email protected]', '[email protected]'])

def test_declaration(self):
"Group declarations can only contain values and a docstring"
Expand Down
2 changes: 1 addition & 1 deletion dbsettings/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
def set_defaults(app, *defaults):
"Installs a set of default values during syncdb processing"
"""Installs a set of default values during syncdb processing"""
from django.core.exceptions import ImproperlyConfigured
from django.db.models import signals
from dbsettings.loading import get_setting_storage, set_setting_value
Expand Down
28 changes: 21 additions & 7 deletions dbsettings/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,17 @@
class Value(object):

creation_counter = 0
unitialized_value = None

def __init__(self, description=None, help_text=None, choices=None):
def __init__(self, description=None, help_text=None, choices=None, required=True, default=None):
self.description = description
self.help_text = help_text
self.choices = choices or []
self.required = required
if default == None:
self.default = self.unitialized_value
else:
self.default = default

self.creation_counter = Value.creation_counter
Value.creation_counter += 1
Expand Down Expand Up @@ -64,23 +70,23 @@ def __set__(self, instance, value):
# Subclasses should override the following methods where applicable

def to_python(self, value):
"Returns a native Python object suitable for immediate use"
"""Returns a native Python object suitable for immediate use"""
return value

def get_db_prep_save(self, value):
"Returns a value suitable for storage into a CharField"
"""Returns a value suitable for storage into a CharField"""
return unicode(value)

def to_editor(self, value):
"Returns a value suitable for display in a form widget"
"""Returns a value suitable for display in a form widget"""
return unicode(value)

###############
# VALUE TYPES #
###############

class BooleanValue(Value):

unitialized_value = False
class field(forms.BooleanField):

def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -164,15 +170,18 @@ def __init__(self, *args, **kwargs):
forms.IntegerField.__init__(self, *args, **kwargs)

class StringValue(Value):
unitialized_value = ''
field = forms.CharField

class TextValue(Value):
unitialized_value = ''
field = forms.CharField

def to_python(self, value):
return unicode(value)

class EmailValue(Value):
unitialized_value = ''
field = forms.EmailField

def to_python(self, value):
Expand All @@ -186,10 +195,15 @@ class MultiSeparatorValue(TextValue):
separator string (default is semi-colon as above).
"""

def __init__(self, description=None, help_text=None, separator=';'):
def __init__(self, description=None, help_text=None, separator=';', required=True, default=None):
self.separator = separator
if default != None:
# convert from list to string
default = separator.join(default)
super(MultiSeparatorValue, self).__init__(description=description,
help_text=help_text)
help_text=help_text,
required=required,
default=default)

class field(forms.CharField):

Expand Down