diff options
Diffstat (limited to 'archaeological_operations/views.py')
| -rw-r--r-- | archaeological_operations/views.py | 144 | 
1 files changed, 111 insertions, 33 deletions
diff --git a/archaeological_operations/views.py b/archaeological_operations/views.py index 70732d04e..bf33e45b6 100644 --- a/archaeological_operations/views.py +++ b/archaeological_operations/views.py @@ -502,7 +502,37 @@ operation_modify_parcels = get_parcel_modify(  RELATION_FORMSET_EXTRA_FORM = 3 -def get_relation_modify(model, model_relation, url_name, formset_class, filter_operations=False): +def _formset_get_deleted(request, data, pk_key): +    new_data = dict(request.POST) +    new_data = {k: new_data[k][0] for k in new_data}  # convert POST to classic dict +    no_values = list(range(data["form-TOTAL_FORMS"])) +    deleted = {} +    for k, value in list(new_data.items()): +        if not value or not k.startswith("form-"): +            continue +        try: +            form_number = int(k.split("-")[1]) +        except (ValueError, IndexError) as __: +            continue +        if k.endswith("-DELETE"): +            if new_data.get(f"form-{form_number}-{pk_key}", None): +                deleted[form_number] = new_data[f"form-{form_number}-{pk_key}"] +                if form_number not in no_values:  # put it back in no values +                    no_values.append(form_number) +            else: +                new_data.pop(k) +        elif form_number in no_values and form_number not in deleted: +            no_values.pop(no_values.index(form_number)) +    for no_value in no_values: +        for k in list(new_data.keys()): +            if k.startswith(f"form-{no_value}-"): +                new_data.pop(k) +    data["form-TOTAL_FORMS"] = data["form-TOTAL_FORMS"] - len(no_values) +    new_data.update(data) +    return new_data, deleted + + +def get_relation_modify(model, model_relation, formset_class, url_name, filter_operations=False):      def _modify_relation(request, pk, current_right=None):          try:              item = model.objects.get(pk=pk) @@ -512,6 +542,7 @@ def get_relation_modify(model, model_relation, url_name, formset_class, filter_o              if not item.is_own(request.user):                  raise PermissionDenied()          relations = model_relation.objects.filter(left_record_id=pk).all() +        form_kwargs = {"left_record": item}          items, current_items = [], []          if filter_operations: @@ -539,37 +570,9 @@ def get_relation_modify(model, model_relation, url_name, formset_class, filter_o          if filter_operations:              data["CURRENT_ITEMS"] = items          if request.method == 'POST': -            new_data = dict(request.POST) -            new_data = {k: new_data[k][0] for k in new_data}  # convert POST to classic dict -              # remove empty lines and get deleted -            no_values = list(range(data["form-TOTAL_FORMS"])) -            deleted = {} -            for k, value in list(new_data.items()): -                if not value or not k.startswith("form-"): -                    continue -                try: -                    form_number = int(k.split("-")[1]) -                except (ValueError, IndexError) as __: -                    continue -                if k.endswith("-DELETE"): -                    if new_data.get(f"form-{form_number}-pk", None): -                        deleted[form_number] = new_data[f"form-{form_number}-pk"] -                        if form_number not in no_values:  # put it back in no values -                            no_values.append(form_number) -                    else: -                        new_data.pop(k) -                elif form_number in no_values and form_number not in deleted: -                    no_values.pop(no_values.index(form_number)) -            for no_value in no_values: -                for k in list(new_data.keys()): -                    if k.startswith(f"form-{no_value}-"): -                        new_data.pop(k) -            data["form-TOTAL_FORMS"] = data["form-TOTAL_FORMS"] - len(no_values) - -            new_data.update(data) -            formset = formset_class(data=new_data) - +            new_data, deleted = _formset_get_deleted(request, data, "pk") +            formset = formset_class(data=new_data, form_kwargs=form_kwargs)              if formset.is_valid():                  is_valid = True                  # delete @@ -609,7 +612,7 @@ def get_relation_modify(model, model_relation, url_name, formset_class, filter_o                  if is_valid:                      return redirect(reverse(url_name, args=[pk]))          else: -            formset = formset_class(initial=initial, data=data) +            formset = formset_class(initial=initial, data=data, form_kwargs=form_kwargs)          return render(request, 'ishtar/forms/modify_relations.html', {              'formset': formset, @@ -620,10 +623,85 @@ def get_relation_modify(model, model_relation, url_name, formset_class, filter_o  operation_modify_relations = get_relation_modify(      models.Operation, models.RecordRelations, -    "operation-relation-modify", forms.RecordRelationsFormSet +    forms.RecordRelationsFormSet, "operation-relation-modify"  ) +RELATION_LIMIT = 50 + + +def operation_site_modify(model, related_model, related_key, formset_class, url_name): + +    def _get_initial(q_relations): +        initial = [] +        current_relation_ids = q_relations.values_list("id", flat=True) +        excess = current_relation_ids.count() > RELATION_LIMIT and RELATION_LIMIT +        for relation_id in current_relation_ids[:RELATION_LIMIT]: +            initial.append({ +                "right_record": relation_id, +            }) +        return initial, current_relation_ids, excess +    get_initial = _get_initial + +    def view(request, pk, window_id=None, current_right=None): +        try: +            item = model.objects.get(pk=pk) +        except model.DoesNotExist: +            raise Http404() +        if "_own_" in current_right: +            if not item.is_own(request.user): +                raise PermissionDenied() +        q_relations = getattr(item, related_key) +        initial, current_relation_ids, excess = get_initial(q_relations) +        if request.method == 'POST': +            formset = formset_class(data=request.POST) +            if formset.is_valid(): +                deleted_ids = [] +                for form in formset.deleted_forms: +                    deleted_id = form.cleaned_data.get("right_record", None) +                    try: +                        deleted_id = int(deleted_id) +                    except (ValueError, TypeError): +                        continue +                    deleted_ids.append(deleted_id) +                    if deleted_id in current_relation_ids: +                        try: +                            del_item = related_model.objects.get(pk=deleted_id) +                        except related_model.DoesNotExist: +                            continue +                        q_relations.remove(del_item) + +                for idx_form, data in enumerate(formset.cleaned_data): +                    if not data.get('right_record'): +                        continue +                    try: +                        new_item_id = int(data.get("right_record")) +                        if new_item_id in deleted_ids or new_item_id in current_relation_ids: +                            continue +                        new_item = related_model.objects.get(pk=new_item_id) +                    except (ValueError, TypeError, related_model.DoesNotExist): +                        continue +                    q_relations.add(new_item) +                initial, __, __ = get_initial(q_relations) +                formset = formset_class(initial=initial) +        else: +            formset = formset_class(initial=initial) + +        return render(request, 'ishtar/forms/modify_relations.html', { +            'formset': formset, +            "url": reverse(url_name, args=[pk]), +            "window_id": window_id, +            "excess": str( +                _("Too many relations. Only the first {limit} items are displayed.") +            ).format(limit=excess) if excess else None +        }) +    return view + + +operation_site_modify_relations = operation_site_modify(models.Operation, models.ArchaeologicalSite, "archaeological_sites", forms.OpeSiteRelationsFormSet, "operation-site-relations-modify") +site_operation_modify_relations = operation_site_modify(models.ArchaeologicalSite, models.Operation, "operations", forms.SiteOpeRelationsFormSet, "site-operation-relations-modify") + +  # archaeological sites  | 
