From f7a4bd783df87aea052aba07b2a48001b6389772 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Tue, 21 Mar 2017 19:18:15 +0100 Subject: Finds search: conditionnal search (warehouse module available) for warehouses and containers (refs #3416) --- ishtar_common/wizards.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'ishtar_common/wizards.py') diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index 874b68eae..7950bcc7e 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -132,6 +132,7 @@ class Wizard(NamedUrlWizardView): current_object_key = 'pk' ignore_init_steps = [] file_storage = default_storage + main_item_select_keys = ('selec-',) saved_args = {} # argument to pass on object save @@ -217,8 +218,9 @@ class Wizard(NamedUrlWizardView): dct = {'current_step_label': self.form_list[current_step].form_label, 'wizard_label': self.label, 'current_object': self.get_current_object(), - 'is_search': current_step.startswith('selec-') - if current_step else False + 'is_search': bool( + [k for k in self.main_item_select_keys + if current_step.startswith(k)]) if current_step else False } context.update(dct) if step == current_step: @@ -1004,20 +1006,24 @@ class Wizard(NamedUrlWizardView): def get_current_object(self): """Get the current object for an instancied wizard""" current_obj = None - main_form_key = 'selec-' + self.url_name - try: - idx = self.session_get_value(main_form_key, self.current_object_key) - idx = int(idx) - current_obj = self.model.objects.get(pk=idx) - except(TypeError, ValueError, ObjectDoesNotExist): - pass + for key in self.main_item_select_keys: + main_form_key = key + self.url_name + try: + idx = int(self.session_get_value(main_form_key, + self.current_object_key)) + current_obj = self.model.objects.get(pk=idx) + break + except(TypeError, ValueError, ObjectDoesNotExist): + pass return current_obj def get_form_initial(self, step, data=None): current_obj = self.get_current_object() current_step = self.steps.current request = self.request - if step.startswith('selec-') and step in self.form_list \ + step_is_main_select = bool([k for k in self.main_item_select_keys + if step.startswith(k)]) + if step_is_main_select and step in self.form_list \ and 'pk' in self.form_list[step].associated_models: model_name = self.form_list[step]\ .associated_models['pk'].__name__.lower() -- cgit v1.2.3 From efd503d99267332b49011d1127d1819592f64101 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 24 Mar 2017 17:47:33 +0100 Subject: Wizard: manage readonly forms (refs #3563) --- ishtar_common/forms.py | 39 +++++++++++++++++++++++++++++++++++++-- ishtar_common/wizards.py | 2 ++ 2 files changed, 39 insertions(+), 2 deletions(-) (limited to 'ishtar_common/wizards.py') diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py index 42d74f9ef..ecae18c5e 100644 --- a/ishtar_common/forms.py +++ b/ishtar_common/forms.py @@ -22,6 +22,7 @@ Forms definition """ import datetime import re +import types from django import forms from django.core.urlresolvers import reverse @@ -94,7 +95,32 @@ class FinalDeleteForm(FinalForm): confirm_end_msg = _(u"Are you sure you want to delete?") +def get_readonly_clean(key): + def func(self): + instance = getattr(self, 'instance', None) + if instance and getattr(instance, key): + return getattr(instance, key) + else: + return self.cleaned_data[key] + return func + + class FormSet(BaseFormSet): + def __init__(self, *args, **kwargs): + self.readonly = False + if 'readonly' in kwargs: + self.readonly = kwargs.pop('readonly') + self.can_delete = False + # no extra fields + if 'data' in kwargs: + prefix = "" + if "prefix" in kwargs: + prefix = kwargs['prefix'] + if prefix + '-INITIAL_FORMS' in kwargs['data']: + kwargs['data'][prefix + '-TOTAL_FORMS'] = \ + kwargs["data"][prefix + '-INITIAL_FORMS'] + super(FormSet, self).__init__(*args, **kwargs) + def check_duplicate(self, key_names, error_msg=""): """Check for duplicate items in the formset""" if any(self.errors): @@ -117,8 +143,17 @@ class FormSet(BaseFormSet): def add_fields(self, form, index): super(FormSet, self).add_fields(form, index) - form.fields[DELETION_FIELD_NAME].label = '' - form.fields[DELETION_FIELD_NAME].widget = widgets.DeleteWidget() + if self.readonly: + for k in form.fields: + # django 1.9: use disabled + form.fields[k].widget.attrs['readonly'] = True + clean = get_readonly_clean(k) + clean.__name__ = 'clean_' + k + clean.__doc__ = 'autogenerated: clean_' + k + setattr(form, clean.__name__, types.MethodType(clean, form)) + if self.can_delete: + form.fields[DELETION_FIELD_NAME].label = '' + form.fields[DELETION_FIELD_NAME].widget = widgets.DeleteWidget() class TableSelect(forms.Form): diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index 7950bcc7e..ddb2bc2ac 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -408,6 +408,8 @@ class Wizard(NamedUrlWizardView): for form in form_list: if not form.is_valid(): return self.render(form) + if hasattr(form, 'readonly') and form.readonly: + continue base_form = hasattr(form, 'forms') and form.forms[0] or form associated_models = hasattr(base_form, 'associated_models') and \ base_form.associated_models or {} -- cgit v1.2.3 From 25bfdf136bd2bd7658878d25e337b02b8150915d Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Sat, 1 Apr 2017 19:06:35 +0200 Subject: Operation wizard: an operation cannot be related to herself (refs #3578) --- archaeological_operations/forms.py | 28 +++++++++++++++++++++++++++- archaeological_operations/wizards.py | 11 ++++++++++- ishtar_common/wizards.py | 2 +- 3 files changed, 38 insertions(+), 3 deletions(-) (limited to 'ishtar_common/wizards.py') diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py index 6423962d8..4796ef68c 100644 --- a/archaeological_operations/forms.py +++ b/archaeological_operations/forms.py @@ -387,6 +387,9 @@ class RecordRelationsForm(ManageOldType, forms.Form): validators=[valid_id(models.Operation)], required=False) def __init__(self, *args, **kwargs): + self.left_record = None + if 'left_record' in kwargs: + self.left_record = kwargs.pop('left_record') super(RecordRelationsForm, self).__init__(*args, **kwargs) self.fields['relation_type'].choices = \ models.RelationType.get_types( @@ -413,6 +416,9 @@ class RecordRelationsForm(ManageOldType, forms.Form): cleaned_data.get('right_record', None)): raise forms.ValidationError( _(u"You should select a relation type.")) + if str(cleaned_data.get('right_record')) == str(self.left_record.pk): + raise forms.ValidationError( + _(u"An operation cannot be related to herself.")) return cleaned_data @classmethod @@ -447,7 +453,27 @@ class RecordRelationsForm(ManageOldType, forms.Form): result.append((_("Deleted relations"), u" ; ".join(deleted))) return result -RecordRelationsFormSet = formset_factory(RecordRelationsForm, can_delete=True) + +class RecordRelationsFormSetBase(FormSet): + # passing left_record should be nicely done with form_kwargs with Django 1.9 + # with no need of all these complications + + def __init__(self, *args, **kwargs): + self.left_record = None + if 'left_record' in kwargs: + self.left_record = kwargs.pop('left_record') + super(RecordRelationsFormSetBase, self).__init__(*args, **kwargs) + + def _construct_forms(self): + # instantiate all the forms and put them in self.forms + self.forms = [] + for i in xrange(self.total_form_count()): + self.forms.append(self._construct_form( + i, left_record=self.left_record)) + + +RecordRelationsFormSet = formset_factory( + RecordRelationsForm, can_delete=True, formset=RecordRelationsFormSetBase) RecordRelationsFormSet.form_label = _(u"Relations") diff --git a/archaeological_operations/wizards.py b/archaeological_operations/wizards.py index 5410b37f8..c132c24be 100644 --- a/archaeological_operations/wizards.py +++ b/archaeological_operations/wizards.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2012-2016 Étienne Loks +# Copyright (C) 2012-2017 Étienne Loks # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -275,6 +275,15 @@ class OperationModificationWizard(OperationWizard): modification = True filter_owns = {'selec-operation_modification': ['pk']} + def get_form_kwargs(self, step, **kwargs): + kwargs = super(OperationModificationWizard, self).get_form_kwargs( + step, **kwargs) + print(step) + if step != "relations-operation_modification": + return kwargs + kwargs["left_record"] = self.get_current_object() + return kwargs + class OperationClosingWizard(ClosingWizard): model = models.Operation diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index ddb2bc2ac..61923d920 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -819,7 +819,7 @@ class Wizard(NamedUrlWizardView): # get a form key frm = form.form if callable(frm): - frm = frm() + frm = frm(self.get_form_kwargs(step)) total_field = 0 if hasattr(frm, 'count_valid_fields'): -- cgit v1.2.3 From 3f18460f80c89d5de4420fbe53fb39991cd08105 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Mon, 3 Apr 2017 19:15:13 +0200 Subject: Fix find modify action (refs #3405) --- archaeological_finds/views.py | 2 +- ishtar_common/models.py | 2 ++ ishtar_common/wizards.py | 8 +++++++- 3 files changed, 10 insertions(+), 2 deletions(-) (limited to 'ishtar_common/wizards.py') diff --git a/archaeological_finds/views.py b/archaeological_finds/views.py index 03094cbb0..680faf421 100644 --- a/archaeological_finds/views.py +++ b/archaeological_finds/views.py @@ -169,7 +169,7 @@ find_modification_wizard = FindModificationWizard.as_view([ def find_modify(request, pk): - # view = find_modification_wizard(request) + find_modification_wizard(request) FindModificationWizard.session_set_value( request, 'selec-find_modification', 'pk', pk, reset=True) return redirect( diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 7873b63f8..bf5c6056a 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -191,6 +191,8 @@ def valid_ids(cls): def func(value): if "," in value: value = value.split(",") + if type(value) not in (list, tuple): + value = [value] for v in value: try: cls.objects.get(pk=v) diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index 61923d920..8d787d733 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -51,10 +51,16 @@ class MultiValueDict(BaseMultiValueDict): v = v() if type(v) in (list, tuple) and len(v) > 1: v = ",".join(v) - else: + elif type(v) not in (int, unicode): v = super(MultiValueDict, self).get(*args, **kwargs) return v + def getlist(self, *args, **kwargs): + lst = super(MultiValueDict, self).getlist(*args, **kwargs) + if type(lst) not in (tuple, list): + lst = [lst] + return lst + def check_rights(rights=[], redirect_url='/'): """ -- cgit v1.2.3