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 |