diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2017-11-24 19:39:06 +0100 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2017-11-24 19:39:06 +0100 |
commit | 651524bf93ee64f5f28605884f6b60256db43d1f (patch) | |
tree | 3eab6d3ab5f8da3f4cb7c803b2237928b27b9d74 /ishtar_common/forms.py | |
parent | 17bf67ec257d0d10decedc44a88d0ab5197c2ba8 (diff) | |
parent | 9384f39f8fd63f1e004d3abe75cb737c6651e3ed (diff) | |
download | Ishtar-651524bf93ee64f5f28605884f6b60256db43d1f.tar.bz2 Ishtar-651524bf93ee64f5f28605884f6b60256db43d1f.zip |
Merge branch 'develop' into develop-bootstrap
Diffstat (limited to 'ishtar_common/forms.py')
-rw-r--r-- | ishtar_common/forms.py | 126 |
1 files changed, 117 insertions, 9 deletions
diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py index 985d2c3cf..36b0ef413 100644 --- a/ishtar_common/forms.py +++ b/ishtar_common/forms.py @@ -34,7 +34,7 @@ from django.utils.translation import ugettext_lazy as _ import models import widgets -from wizards import MultiValueDict +from ishtar_common.utils import MultiValueDict # from formwizard.forms import NamedUrlSessionFormWizard @@ -105,7 +105,92 @@ def get_readonly_clean(key): return func -class FormSet(BaseFormSet): +class CustomForm(object): + form_admin_name = "" + form_slug = "" + need_user_for_initialization = True + + def __init__(self, *args, **kwargs): + current_user = None + if 'user' in kwargs: + try: + current_user = kwargs.pop('user').ishtaruser + except AttributeError: + pass + super(CustomForm, self).__init__(*args, **kwargs) + available, excluded = self.check_availability_and_excluded_fields( + current_user) + for exc in excluded: + if hasattr(self, 'fields'): + self.remove_field(exc) + else: + # formset + for form in self.forms: + if exc in form.fields: + form.fields.pop(exc) + + def are_available(self, keys): + for k in keys: + if k not in self.fields: + return False + return True + + def remove_field(self, key): + if key in self.fields: + self.fields.pop(key) + + @classmethod + def check_availability_and_excluded_fields(cls, current_user): + if not current_user: + return True, [] + base_q = {"form": cls.form_slug, 'available': True} + # order is important : try for user, user type then all + query_dicts = [] + if current_user: + dct = base_q.copy() + dct.update({'users__pk': current_user.pk}) + query_dicts = [dct] + for user_type in current_user.person.person_types.all(): + dct = base_q.copy() + dct.update({'user_types__pk': user_type.pk}), + query_dicts.append(dct) + dct = base_q.copy() + dct.update({'apply_to_all': True}) + query_dicts.append(dct) + excluded_lst = [] + for query_dict in query_dicts: + q = models.CustomForm.objects.filter(**query_dict) + if not q.count(): + continue + # todo: prevent multiple result in database + form = q.all()[0] + if not form.enabled: + return False, [] + for excluded in form.excluded_fields.all(): + # could have be filtered previously + excluded_lst.append(excluded.field) + break + return True, excluded_lst + + @classmethod + def get_custom_fields(cls): + if hasattr(cls, 'base_fields'): + fields = cls.base_fields + else: + # formset + fields = cls.form.base_fields + customs = [] + for key in fields: + field = fields[key] + # cannot customize display of required and hidden field + # field with no label are also rejected + if field.required or field.widget.is_hidden or not field.label: + continue + customs.append((key, field.label)) + return sorted(customs, key=lambda x: x[1]) + + +class FormSet(CustomForm, BaseFormSet): def __init__(self, *args, **kwargs): self.readonly = False if 'readonly' in kwargs: @@ -261,8 +346,31 @@ class IshtarForm(forms.Form): self.fields[k].widget.attrs['class'] = 'form-control' +class FieldType(object): + def __init__(self, key, model, is_multiple=False, extra_args=None): + self.key = key + self.model = model + self.is_multiple = is_multiple + self.extra_args = extra_args + + def get_choices(self, initial=None): + args = { + 'empty_first': not self.is_multiple, + 'initial': initial + } + if self.extra_args: + args.update(self.extra_args) + return self.model.get_types(**args) + + def get_help(self): + args = {} + if self.extra_args: + args.update(self.extra_args) + return self.model.get_help(**args) + + class ManageOldType(IshtarForm): - TYPES = [] # (field_name, model, is_multiple) list + TYPES = [] # FieldType list def __init__(self, *args, **kwargs): """ @@ -301,12 +409,12 @@ class ManageOldType(IshtarForm): self.init_data[k].append(val) self.init_data = MultiValueDict(self.init_data) super(ManageOldType, self).__init__(*args, **kwargs) - for field_name, model, is_multiple in self.TYPES: - self.fields[field_name].choices = \ - model.get_types( - empty_first=not is_multiple, - initial=self.init_data.get(field_name)) - self.fields[field_name].help_text = model.get_help() + for field in self.TYPES: + if field.key not in self.fields: + continue + self.fields[field.key].choices = field.get_choices( + initial=self.init_data.get(field.key)) + self.fields[field.key].help_text = field.get_help() class DocumentGenerationForm(forms.Form): |