From 872bc0f6b00c44a5978a826c063a3f1e50dd4b15 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 13 Nov 2025 17:18:53 +0100 Subject: ✨ datings refactoring: add view/form MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- archaeological_context_records/forms.py | 86 ++++++++++++++++------ archaeological_context_records/models.py | 2 +- .../templates/ishtar/sheet_contextrecord.html | 11 +-- archaeological_context_records/urls.py | 8 ++ archaeological_context_records/views.py | 43 ++++++++++- 5 files changed, 120 insertions(+), 30 deletions(-) (limited to 'archaeological_context_records') diff --git a/archaeological_context_records/forms.py b/archaeological_context_records/forms.py index df074c768..36f6ea516 100644 --- a/archaeological_context_records/forms.py +++ b/archaeological_context_records/forms.py @@ -43,7 +43,6 @@ from archaeological_context_records import models from ishtar_common.forms import ( FinalForm, - FormSet, reverse_lazy, get_form_selection, ManageOldType, @@ -512,28 +511,6 @@ class RecordFormGeneral(CustomForm, ManageOldType): return cleaned_data -class DatingForm(ManageOldType, forms.Form): - form_label = _("Dating") - base_model = "dating" - associated_models = { - "dating_type": models.DatingType, - "quality": models.DatingQuality, - "period": models.Period, - } - period = forms.ChoiceField(label=_("Chronological period"), choices=[]) - start_date = forms.IntegerField(label=_("Start date"), required=False) - end_date = forms.IntegerField(label=_("End date"), required=False) - quality = forms.ChoiceField(label=_("Quality"), required=False, choices=[]) - dating_type = forms.ChoiceField(label=_("Dating type"), required=False, choices=[]) - precise_dating = forms.CharField(label=_("Precise on this dating"), required=False) - - TYPES = [ - FieldType("dating_type", models.DatingType), - FieldType("quality", models.DatingQuality), - FieldType("period", models.Period), - ] - - class RecordFormInterpretation(CustomForm, ManageOldType): HEADERS = {} form_label = _("Interpretation") @@ -921,3 +898,66 @@ class QAContextRecordFormMulti(QAForm): def _set_qa_relation_type(self, item, __): pass + + +class QADating(ManageOldType, forms.Form): + form_label = _("Dating") + associated_models = { + "dating_type_id": models.DatingType, + "quality_id": models.DatingQuality, + "period_id": models.Period, + } + pk = forms.IntegerField(required=False, widget=forms.HiddenInput) + reference = forms.CharField( + label=_("Reference"), validators=[validators.MaxLengthValidator(400)], + required=False + ) + period_id = forms.ChoiceField(label=_("Chronological period"), choices=[], + required=False) + start_date = forms.IntegerField(label=_("Start date"), required=False) + end_date = forms.IntegerField(label=_("End date"), required=False) + quality_id = forms.ChoiceField(label=_("Quality"), required=False, choices=[]) + dating_type_id = forms.ChoiceField(label=_("Dating type"), required=False, choices=[]) + precise_dating = forms.CharField(label=_("Precise on this dating"), required=False, + widget=forms.Textarea) + + TYPES = [ + FieldType("dating_type_id", models.DatingType), + FieldType("quality_id", models.DatingQuality), + FieldType("period_id", models.Period), + ] + + def __init__(self, *args, **kwargs): + self.dating_model = kwargs.pop("dating_model") + self.current_item = kwargs.pop("current_item") + return super().__init__(*args, **kwargs) + + def clean(self): + data = self.cleaned_data + reference = data['reference'] + q_attr = { + "reference": reference, + self.dating_model.CURRENT_MODEL_ATTR + "_id": self.current_item.pk + } + q = self.dating_model.objects.filter(**q_attr) + if data.get("pk", None): + q = q.exclude(pk=data["pk"]) + if q.count(): + raise forms.ValidationError( + _("This reference already exists for this item.") + ) + if any(1 for k in self.cleaned_data if self.cleaned_data[k]): + return data + raise forms.ValidationError(_("No data provided.")) + + def save(self): + data = copy(self.cleaned_data) + data[self.dating_model.CURRENT_MODEL_ATTR + "_id"] = self.current_item.pk + for attr in ['period_id', 'quality_id', 'dating_type_id']: + if not data.get(attr, None): + data[attr] = None + if data.get("pk", None): + pk = data.pop("pk") + self.dating_model.objects.filter(pk=pk).update(**data) + return + self.dating_model.objects.create(**data) diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py index 0c8a18f43..63e6a773d 100644 --- a/archaeological_context_records/models.py +++ b/archaeological_context_records/models.py @@ -1376,7 +1376,7 @@ class ContextRecord( return self.full_label() def _generate_cached_periods(self): - return " & ".join(dating.period.label for dating in self.datings.all()) + return " & ".join(period.label for period in self.periods.all()) def _generate_cached_related_context_records(self): return self.detailed_related_context_records() diff --git a/archaeological_context_records/templates/ishtar/sheet_contextrecord.html b/archaeological_context_records/templates/ishtar/sheet_contextrecord.html index 869d6edd5..bd766f9f6 100644 --- a/archaeological_context_records/templates/ishtar/sheet_contextrecord.html +++ b/archaeological_context_records/templates/ishtar/sheet_contextrecord.html @@ -28,6 +28,7 @@ {% with display_interpretation=item|safe_or:"identifications.count"|or_:item.interpretation|or_:item.activity %} {% with display_datations=dating_list|or_:item.taq|or_:item.taq_estimated|or_:item.tpq|or_:item.tpq_estimated|or_:has_cultural_attributions %} {% with can_view_finds=permission_view_own_find|or_:permission_view_find %} +{% with can_change=permission_change_own_find|or_:permission_change_find %} {% with has_finds=item|safe_or:"base_finds.count"|safe_and_not:"base_finds_not_available" %} {% with display_finds=has_finds|and_:can_view_finds %} {% with display_data=item.data %} @@ -50,7 +51,7 @@ {% endif %} - {% if display_datations %} + {% if display_datations or can_change %}