diff options
Diffstat (limited to 'archaeological_context_records/models.py')
| -rw-r--r-- | archaeological_context_records/models.py | 110 |
1 files changed, 99 insertions, 11 deletions
diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py index 29deae5ee..0c8a18f43 100644 --- a/archaeological_context_records/models.py +++ b/archaeological_context_records/models.py @@ -30,12 +30,15 @@ from django.db.models import Q from django.db.models.signals import post_delete, post_save, m2m_changed from django.urls import reverse, reverse_lazy -from ishtar_common.utils import gettext_lazy as _, pgettext_lazy, pgettext +from ishtar_common.utils import get_generated_id, gettext_lazy as _, pgettext_lazy, \ + pgettext + from django.utils.text import slugify from ishtar_common.utils import ( cached_label_changed, m2m_historization_changed, + related_historization_changed, post_save_geo, SearchAltName, ) @@ -101,12 +104,18 @@ post_save.connect(post_save_cache, sender=DatingQuality) post_delete.connect(post_save_cache, sender=DatingQuality) -class Dating(models.Model, SerializeItem): +class BaseDating(models.Model, SerializeItem): SLUG = "dating" SERIALIZE_EXCLUDE = ["find", "context_record"] + CURRENT_MODEL = None + CURRENT_MODEL_ATTR = None uuid = models.UUIDField(default=uuid.uuid4) + reference = models.TextField(_("Reference"), blank=True, default="") + external_id = models.TextField(_("External ID"), blank=True, default="") period = models.ForeignKey( - Period, verbose_name=_("Chronological period"), on_delete=models.PROTECT + Period, verbose_name=_("Chronological period"), on_delete=models.PROTECT, + blank=True, + null=True, ) start_date = models.IntegerField(_("Start date"), blank=True, null=True) end_date = models.IntegerField(_("End date"), blank=True, null=True) @@ -154,8 +163,7 @@ class Dating(models.Model, SerializeItem): } class Meta: - verbose_name = _("Dating") - verbose_name_plural = _("Datings") + abstract = True def __str__(self): if self.precise_dating and self.precise_dating.strip(): @@ -171,6 +179,8 @@ class Dating(models.Model, SerializeItem): def get_values(self, prefix="", no_values=False, filtr=None, **kwargs): values = {} + if not filtr or prefix + "reference" in filtr: + values[prefix + "reference"] = self.reference if not filtr or prefix + "period" in filtr: values[prefix + "period"] = str(self.period) if not filtr or prefix + "start_date" in filtr: @@ -188,6 +198,7 @@ class Dating(models.Model, SerializeItem): return values HISTORY_ATTR = [ + "reference", "period", "start_date", "end_date", @@ -198,7 +209,8 @@ class Dating(models.Model, SerializeItem): def history_compress(self): values = {} - for attr in self.HISTORY_ATTR: + attrs = self.HISTORY_ATTR + [self.CURRENT_MODEL_ATTR + "_id"] + for attr in attrs: val = getattr(self, attr) if hasattr(val, "history_compress"): val = val.history_compress() @@ -244,6 +256,7 @@ class Dating(models.Model, SerializeItem): attribute is identical """ for attr in [ + "reference", "period", "start_date", "end_date", @@ -283,6 +296,7 @@ class Dating(models.Model, SerializeItem): for dating in obj.datings.order_by("pk").all(): key = ( dating.period.pk, + dating.reference, dating.start_date, dating.end_date, dating.dating_type, @@ -294,6 +308,50 @@ class Dating(models.Model, SerializeItem): continue dating.delete() + @property + def q_parent(self): + if not self.pk or not self.CURRENT_MODEL: + return + if getattr(self, "__q_parent", None): + return self.__q_parent + q = self.CURRENT_MODEL.objects.filter(datings__pk=self.pk) + if q.count(): + self.__q_parent = q + return q + + @property + def parent_external_id(self): + if not self.pk or not self.q_parent: + return "" + return self.q_parent.all()[0].external_id + + @property + def auto_id(self): + if not self.pk or not self.q_parent: + return 0 + parent_pk = self.q_parent.all()[0].pk + attr = "context_record" if self.CURRENT_MODEL == ContextRecord else "find" + for idx, dating_pk in enumerate( + self.__class__.objects.filter(**{attr: parent_pk}).values_list( + "pk", flat=True).all()).all(): + if dating_pk == self.pk: + return idx + 1 + return 0 + + def save(self, *args, **kwargs): + super().save(*args, **kwargs) + if not self.pk: + return + external_id = get_generated_id("dating_external_id", self) + if external_id != self.external_id: + self.__class__.objects.filter(pk=self.pk).update(external_id=external_id) + + +class Dating(BaseDating): + class Meta: + verbose_name = _("Dating - deprecated") + verbose_name_plural = _("Datings - deprecated") + class Unit(GeneralType): order = models.IntegerField(_("Order")) @@ -693,6 +751,10 @@ class ContextRecord( pgettext_lazy("key for text search", "excavation-technique"), "excavation_technics__label__iexact", ), + "periods": SearchAltName( + pgettext_lazy("key for text search", "period"), + "periods__label__iexact", + ), "cultural_attributions": SearchAltName( pgettext_lazy("key for text search", "cultural-attribution"), "cultural_attributions__label__iexact", @@ -790,7 +852,8 @@ class ContextRecord( ("site", "archaeological_site__pk"), ("file", "operation__associated_file__pk"), ] - HISTORICAL_M2M = ["datings", "documentations", "excavation_technics", "identifications"] + HISTORICAL_M2M = ["periods", "datings", "documentations", "excavation_technics", + "identifications"] CACHED_LABELS = ["cached_label", "cached_periods", "cached_related_context_records"] DOWN_MODEL_UPDATE = ["base_finds"] GET_VALUES_EXTRA = ValueGetter.GET_VALUES_EXTRA + ["context_record"] @@ -917,7 +980,8 @@ class ContextRecord( default="", help_text=_("A short description of the location of the context record"), ) - datings = models.ManyToManyField(Dating, related_name="context_records") + datings_old = models.ManyToManyField(Dating, related_name="context_records") + periods = models.ManyToManyField(Period, verbose_name=_("Periods"), blank=True) documentations = models.ManyToManyField(DocumentationType, blank=True) structures = models.ManyToManyField(StructureType, blank=True) textures = models.ManyToManyField(TextureType, blank=True) @@ -1461,11 +1525,35 @@ post_save.connect(context_record_post_save, sender=ContextRecord) m2m_changed.connect(document_attached_changed, sender=ContextRecord.documents.through) m2m_changed.connect(geodata_attached_changed, sender=ContextRecord.geodata.through) -for attr in ContextRecord.HISTORICAL_M2M: - m2m_changed.connect( - m2m_historization_changed, sender=getattr(ContextRecord, attr).through + +class ContextRecordDating(BaseDating): + SERIALIZE_EXCLUDE = ["context_record"] + CURRENT_MODEL = ContextRecord + CURRENT_MODEL_ATTR = "context_record" + + context_record = models.ForeignKey( + ContextRecord, + verbose_name=_("Context record"), + related_name="datings", + on_delete=models.CASCADE, ) + class Meta: + verbose_name = _("Context record dating") + verbose_name_plural = _("Context record datings") + + +for attr in ContextRecord.HISTORICAL_M2M: + if attr == "datings": + model = ContextRecordDating + post_save.connect(related_historization_changed, sender=model) + post_delete.connect(related_historization_changed, sender=model) + else: + model = getattr(ContextRecord, attr).through + m2m_changed.connect( + m2m_historization_changed, sender=model + ) + class RelationType(GeneralRelationType): class Meta: |
