You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

152 lines
5.1 KiB

from six import string_types
from django import forms
from django.core.exceptions import ValidationError
from collections import OrderedDict
from .registries import global_preferences_registry
from .models import GlobalPreferenceModel
from .exceptions import NotFoundInRegistry
class AbstractSinglePreferenceForm(forms.ModelForm):
class Meta:
fields = ("section", "name", "raw_value")
def __init__(self, *args, **kwargs):
self.instance = kwargs.get("instance")
initial = {}
if self.instance:
initial["raw_value"] = self.instance.value
kwargs["initial"] = initial
super(AbstractSinglePreferenceForm, self).__init__(*args, **kwargs)
if self.instance.name:
self.fields["raw_value"] = self.instance.preference.setup_field()
def clean(self):
cleaned_data = super(AbstractSinglePreferenceForm, self).clean()
try:
self.instance.name, self.instance.section = (
cleaned_data["name"],
cleaned_data["section"],
)
except KeyError: # changelist form
pass
try:
self.instance.preference
except NotFoundInRegistry:
raise ValidationError(NotFoundInRegistry.detail_default)
return self.cleaned_data
def save(self, *args, **kwargs):
self.instance.value = self.cleaned_data["raw_value"]
return super(AbstractSinglePreferenceForm, self).save(*args, **kwargs)
class SinglePerInstancePreferenceForm(AbstractSinglePreferenceForm):
class Meta:
fields = ("instance",) + AbstractSinglePreferenceForm.Meta.fields
def clean(self):
cleaned_data = super(AbstractSinglePreferenceForm, self).clean()
try:
self.instance.name, self.instance.section = (
cleaned_data["name"],
cleaned_data["section"],
)
except KeyError: # changelist form
pass
i = cleaned_data.get("instance")
if i:
self.instance.instance = i
try:
self.instance.preference
except NotFoundInRegistry:
raise ValidationError(NotFoundInRegistry.detail_default)
return self.cleaned_data
class GlobalSinglePreferenceForm(AbstractSinglePreferenceForm):
class Meta:
model = GlobalPreferenceModel
fields = AbstractSinglePreferenceForm.Meta.fields
def preference_form_builder(form_base_class, preferences=[], **kwargs):
"""
Return a form class for updating preferences
:param form_base_class: a Form class used as the base. Must have a ``registry` attribute
:param preferences: a list of :py:class:
:param section: a section where the form builder will load preferences
"""
registry = form_base_class.registry
preferences_obj = []
if len(preferences) > 0:
# Preferences have been selected explicitly
for pref in preferences:
if isinstance(pref, string_types):
preferences_obj.append(registry.get(name=pref))
elif type(pref) == tuple:
preferences_obj.append(registry.get(name=pref[0], section=pref[1]))
else:
raise NotImplementedError(
"The data you provide can't be converted to a Preference object"
)
elif kwargs.get("section", None):
# Try to use section param
preferences_obj = registry.preferences(section=kwargs.get("section", None))
else:
# display all preferences in the form
preferences_obj = registry.preferences()
fields = OrderedDict()
instances = []
if "model" in kwargs:
# backward compat, see #212
manager_kwargs = kwargs.get("model")
else:
manager_kwargs = {"instance": kwargs.get("instance", None)}
manager = registry.manager(**manager_kwargs)
for preference in preferences_obj:
f = preference.field
instance = manager.get_db_pref(
section=preference.section.name, name=preference.name
)
f.initial = instance.value
fields[preference.identifier()] = f
instances.append(instance)
form_class = type("Custom" + form_base_class.__name__, (form_base_class,), {})
form_class.base_fields = fields
form_class.preferences = preferences_obj
form_class.instances = instances
form_class.manager = manager
return form_class
def global_preference_form_builder(preferences=[], **kwargs):
"""
A shortcut :py:func:`preference_form_builder(GlobalPreferenceForm, preferences, **kwargs)`
"""
return preference_form_builder(GlobalPreferenceForm, preferences, **kwargs)
class PreferenceForm(forms.Form):
registry = None
def update_preferences(self, **kwargs):
for instance in self.instances:
self.manager.update_db_pref(
instance.preference.section.name,
instance.preference.name,
self.cleaned_data[instance.preference.identifier()],
)
class GlobalPreferenceForm(PreferenceForm):
registry = global_preferences_registry