Source code for mezzanine.conf.forms
from __future__ import unicode_literals
from future.builtins import int
from collections import defaultdict
from django import forms
from django.utils.safestring import mark_safe
from django.utils.translation import activate, get_language, ugettext_lazy as _
from django.template.defaultfilters import urlize
from mezzanine.conf import settings, registry
from mezzanine.conf.models import Setting
if settings.USE_MODELTRANSLATION:
from collections import OrderedDict
from modeltranslation.utils import build_localized_fieldname
FIELD_TYPES = {
bool: forms.BooleanField,
int: forms.IntegerField,
float: forms.FloatField,
}
[docs]class SettingsForm(forms.Form):
"""
Form for settings - creates a field for each setting in
``mezzanine.conf`` that is marked as editable.
"""
def __init__(self, *args, **kwargs):
super(SettingsForm, self).__init__(*args, **kwargs)
# Create a form field for each editable setting's from its type.
active_language = get_language()
for name in sorted(registry.keys()):
setting = registry[name]
if setting["editable"]:
field_class = FIELD_TYPES.get(setting["type"], forms.CharField)
if settings.USE_MODELTRANSLATION and setting["translatable"]:
for code in OrderedDict(settings.LANGUAGES):
try:
activate(code)
except:
pass
else:
self._init_field(setting, field_class, name, code,
active_language,)
else:
self._init_field(setting, field_class, name)
activate(active_language)
def _init_field(self, setting, field_class, name, code=None,
active_language=None,):
"""
Initialize a field whether it is built with a custom name for a
specific translation language or not.
"""
initial = getattr(settings, name)
if (code and code != active_language and
settings.USE_MODELTRANSLATION and setting["translatable"]):
try:
initial = Setting.objects.get(name=name).value
except Setting.DoesNotExist:
pass
kwargs = {
"label": setting["label"] + ":",
"required": setting["type"] in (int, float),
"initial": initial,
"help_text": self.format_help(setting["description"]),
}
if setting["choices"]:
field_class = forms.ChoiceField
kwargs["choices"] = setting["choices"]
field_instance = field_class(**kwargs)
code_name = ('_modeltranslation_' + code if code else '')
self.fields[name + code_name] = field_instance
css_class = field_class.__name__.lower()
field_instance.widget.attrs["class"] = css_class
if code:
field_instance.widget.attrs["class"] += " modeltranslation"
def __iter__(self):
"""
Calculate and apply a group heading to each field and order by
the heading.
"""
fields = list(super(SettingsForm, self).__iter__())
group = lambda field: field.name.split("_", 1)[0].title()
misc = _("Miscellaneous")
groups = defaultdict(int)
for field in fields:
groups[group(field)] += 1
for (i, field) in enumerate(fields):
setattr(fields[i], "group", group(field))
if groups[fields[i].group] == 1:
fields[i].group = misc
return iter(sorted(fields, key=lambda x: (x.group == misc, x.group)))
[docs] def save(self):
"""
Save each of the settings to the DB.
"""
active_language = get_language()
for (name, value) in self.cleaned_data.items():
if name not in registry:
name, code = name.rsplit('_modeltranslation_', 1)
else:
code = None
setting_obj, created = Setting.objects.get_or_create(name=name)
if settings.USE_MODELTRANSLATION:
if registry[name]["translatable"]:
try:
activate(code)
except:
pass
finally:
setting_obj.value = value
activate(active_language)
else:
# Duplicate the value of the setting for every language
for code in OrderedDict(settings.LANGUAGES):
setattr(setting_obj,
build_localized_fieldname('value', code),
value)
else:
setting_obj.value = value
setting_obj.save()
[docs] def format_help(self, description):
"""
Format the setting's description into HTML.
"""
for bold in ("``", "*"):
parts = []
if description is None:
description = ""
for i, s in enumerate(description.split(bold)):
parts.append(s if i % 2 == 0 else "<b>%s</b>" % s)
description = "".join(parts)
description = urlize(description, autoescape=False)
return mark_safe(description.replace("\n", "<br>"))