diff options
Diffstat (limited to 'archaeological_finds/models_finds.py')
| -rw-r--r-- | archaeological_finds/models_finds.py | 264 |
1 files changed, 247 insertions, 17 deletions
diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 57f7a4f79..ae9903af5 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -29,6 +29,7 @@ from django.db.models import Max, Q, F from django.db.models.signals import m2m_changed, post_save, post_delete, pre_delete from django.core.exceptions import ObjectDoesNotExist from django.urls import reverse, reverse_lazy +from django.utils.formats import date_format from ishtar_common.data_importer import post_importer_action, ImporterError from ishtar_common.utils import ( @@ -65,6 +66,7 @@ from ishtar_common.models import ( Imported, IshtarSiteProfile, LightHistorizedItem, + QualifiedBiographicalNote, main_item_pre_delete, MainItem, OrderedHierarchicalType, @@ -124,9 +126,52 @@ post_save.connect(post_save_cache, sender=MaterialTypeQualityType) post_delete.connect(post_save_cache, sender=MaterialTypeQualityType) -class ConservatoryState(HierarchicalType): - order = models.IntegerField(_("Order"), default=10) +class IconographicPatternType(OrderedHierarchicalType): + class Meta: + verbose_name = _("Iconographic pattern type") + verbose_name_plural = _("Iconographic pattern types") + ordering = ( + "order", + "label", + ) + ADMIN_SECTION = _("Finds") + + +post_save.connect(post_save_cache, sender=IconographicPatternType) +post_delete.connect(post_save_cache, sender=IconographicPatternType) + + +class WorkshopMovementStyleType(OrderedHierarchicalType): + class Meta: + verbose_name = _("Workshop, movement, style type") + verbose_name_plural = _("Workshop, movement, style types") + ordering = ( + "order", + "label", + ) + ADMIN_SECTION = _("Finds") + + +post_save.connect(post_save_cache, sender=WorkshopMovementStyleType) +post_delete.connect(post_save_cache, sender=WorkshopMovementStyleType) + +class ListedBuildingProtectionNature(OrderedHierarchicalType): + class Meta: + verbose_name = _("Listed building protection nature") + verbose_name_plural = _("Listed building protection nature") + ordering = ( + "order", + "label", + ) + ADMIN_SECTION = _("Finds") + + +post_save.connect(post_save_cache, sender=ListedBuildingProtectionNature) +post_delete.connect(post_save_cache, sender=ListedBuildingProtectionNature) + + +class ConservatoryState(OrderedHierarchicalType): class Meta: verbose_name = _("Conservatory state type") verbose_name_plural = _("Conservatory state types") @@ -634,7 +679,8 @@ class BaseFind( ) excavation_id = models.TextField(_("Excavation ID"), blank=True, default="") description = models.TextField(_("Description"), blank=True, default="") - comment = models.TextField(_("Comment on the circumstances of discovery"), blank=True, default="") + comment = models.TextField(_("Comment on the circumstances of discovery"), blank=True, + default="") special_interest = models.CharField( _("Special interest"), blank=True, default="", max_length=120 ) @@ -644,6 +690,8 @@ class BaseFind( verbose_name=_("Context Record"), on_delete=models.CASCADE, ) + context_record_comment = models.TextField(_("Details on context record"), + blank=True, default="") discovery_date = models.DateField( _("Discovery date (exact or beginning)"), blank=True, null=True ) @@ -690,6 +738,7 @@ class BaseFind( BASE_SEARCH_VECTORS = [ SearchVectorConfig("label", "raw"), SearchVectorConfig("description", "local"), + SearchVectorConfig("context_record_comment", "local"), SearchVectorConfig("comment", "local"), SearchVectorConfig("cache_short_id", "raw"), SearchVectorConfig("cache_complete_id", "raw"), @@ -1296,6 +1345,7 @@ class Find( "base_finds__context_record__parcel": _("Parcel"), "base_finds__batch": _("Batch"), "base_finds__comment": _("Base find - Comment"), + "base_finds__context_record_comment": _("Base find - Context record details"), "base_finds__description": _("Base find - Description"), "base_finds__topographic_localisation": _( "Base find - " "Topographic localisation" @@ -1319,6 +1369,7 @@ class Find( "base_finds__cache_short_id", "base_finds__cache_complete_id", "base_finds__comment", + "base_finds__context_record_comment", "base_finds__description", "base_finds__topographic_localisation", "base_finds__special_interest", @@ -1348,6 +1399,8 @@ class Find( ("datings__period__label", _("Chronological period")), ("material_types__label", _("Material type")), ("object_types__label", _("Object type")), + ("iconographic_patterns__label", _("Iconographic patterns")), + ("workshop_movement_styles__label", _("Workshop, movement, style")), ("recommended_treatments__label", _("Recommended treatments")), ("conservatory_states__label", _("Conservatory states")), ("integrities__label", _("Integrity")), @@ -1395,6 +1448,7 @@ class Find( "museum_entry_date", "museum_entry_date_end", "museum_allocation_date", + "listed_building_date" ] NUMBER_FIELDS = [ "base_finds__context_record__operation__year", @@ -1440,6 +1494,8 @@ class Find( "documents__image__isnull": "documents__image__isnull", "container__location": "container__location__pk", "container_ref__location": "container_ref__location__pk", + "base_finds__excavation_id": "base_finds__excavation_id", + "editors__person_id": "editors__person_id", # dynamic_table_documents } for table in (TABLE_COLS, TABLE_COLS_FOR_OPE): for key in table: @@ -1459,6 +1515,9 @@ class Find( "label": SearchAltName( pgettext_lazy("key for text search", "free-id"), "label__iexact" ), + "title": SearchAltName( + pgettext_lazy("key for text search", "title"), "title__iexact" + ), "denomination": SearchAltName( pgettext_lazy("key for text search", "denomination"), "denomination__iexact" ), @@ -1517,6 +1576,10 @@ class Find( pgettext_lazy("key for text search", "discovery-comment"), "base_finds__comment__iexact", ), + "base_finds__context_record_comment": SearchAltName( + pgettext_lazy("key for text search", "context-record-comment"), + "base_finds__context_record_comment__iexact", + ), "ope_relation_types": SearchAltName( pgettext_lazy("key for text search", "operation-relation-type"), "ope_relation_types", @@ -1530,6 +1593,24 @@ class Find( "material_types__label__iexact", related_name="material_types", ), + "iconographic_patterns": SearchAltName( + pgettext_lazy("key for text search", "iconographic-patterns"), + "iconographic_patterns__label__iexact", + related_name="iconographic_patterns", + ), + "iconography_notes": SearchAltName( + pgettext_lazy("key for text search", "iconography-notes"), + "iconography_notes__iexact", + ), + "workshop_movement_styles": SearchAltName( + pgettext_lazy("key for text search", "workshop-movement-style"), + "workshop_movement_styles__label__iexact", + related_name="workshop_movement_styles", + ), + "actors": SearchAltName( + pgettext_lazy("key for text search", "actors"), + "actors__cached_label__iexact" + ), "object_types": SearchAltName( pgettext_lazy("key for text search", "object-type"), "object_types__label__iexact", @@ -1558,6 +1639,9 @@ class Find( "description": SearchAltName( pgettext_lazy("key for text search", "description"), "description__iexact" ), + "comparanda": SearchAltName( + pgettext_lazy("key for text search", "comparanda"), "comparanda__iexact" + ), "base_finds__batch": SearchAltName( pgettext_lazy("key for text search", "batch"), "base_finds__batch__label__iexact", @@ -1609,7 +1693,7 @@ class Find( "previous_id": SearchAltName( pgettext_lazy("key for text search", "previous-id"), "previous_id__iexact" ), - #'collection': + # 'collection': # SearchAltName( # pgettext_lazy("key for text search", "collection"), # 'collection__name__iexact'), @@ -1623,8 +1707,17 @@ class Find( "museum_id": SearchAltName( pgettext_lazy("key for text search", "museum-id"), "museum_id__iexact" ), + "museum_id_prefix": SearchAltName( + pgettext_lazy("key for text search", "museum-id-prefix"), + "museum_id_prefix__iexact" + ), + "museum_id_suffix": SearchAltName( + pgettext_lazy("key for text search", "museum-id-suffix"), + "museum_id_suffix__iexact" + ), "cache_complete_museum_id": SearchAltName( - pgettext_lazy("key for text search", "complete-museum-id"), "cache_complete_museum_id__iexact" + pgettext_lazy("key for text search", "complete-museum-id"), + "cache_complete_museum_id__iexact" ), "laboratory_id": SearchAltName( pgettext_lazy("key for text search", "laboratory-id"), @@ -1633,6 +1726,10 @@ class Find( "mark": SearchAltName( pgettext_lazy("key for text search", "mark"), "mark__iexact" ), + "mark_text": SearchAltName( + pgettext_lazy("key for text search", "marking-transcription"), + "mark_text__iexact" + ), "base_finds__discovery_date": SearchAltName( pgettext_lazy("key for text search", "discovery-date"), "base_finds__discovery_date", @@ -1688,6 +1785,10 @@ class Find( pgettext_lazy("key for text search", "conservatory-comment"), "conservatory_comment__iexact", ), + "conservatory_states_details": SearchAltName( + pgettext_lazy("key for text search", "conservatory-states-details"), + "conservatory_states_details__iexact", + ), "length": SearchAltName( pgettext_lazy("key for text search", "length"), "length" ), @@ -1920,6 +2021,22 @@ class Find( pgettext_lazy("key for text search", "museum-observed-quantity"), "museum_observed_quantity" ), + "listed_building_id": SearchAltName( + pgettext_lazy("key for text search", "listed-building-id"), + "listed_building_id__iexact" + ), + "listed_building_protection_nature": SearchAltName( + pgettext_lazy("key for text search", "listed-building-protection-nature"), + "listed_building_protection_nature__label__iexact" + ), + "listed_building_date": SearchAltName( + pgettext_lazy("key for text search", "listed-building-date"), + "listed_building_date" + ), + "listed_building_notes": SearchAltName( + pgettext_lazy("key for text search", "listed-building-notes"), + "listed_building_notes__iexact" + ), } ALT_NAMES.update(BaseHistorizedItem.ALT_NAMES) ALT_NAMES.update(DocumentItem.ALT_NAMES) @@ -1962,6 +2079,7 @@ class Find( SearchVectorConfig("museum_id", "raw"), SearchVectorConfig("label", "raw"), SearchVectorConfig("description", "local"), + SearchVectorConfig("comparanda", "local"), SearchVectorConfig("museum_id_comment", "local"), SearchVectorConfig("mark"), SearchVectorConfig("comment", "local"), @@ -1987,6 +2105,8 @@ class Find( SearchVectorConfig("periods__label", "local"), SearchVectorConfig("integrities__label", "raw"), SearchVectorConfig("material_types__label", "local"), + SearchVectorConfig("iconographic_patterns__label", "local"), + SearchVectorConfig("workshop_movement_styles__label", "local"), SearchVectorConfig("object_types__label", "raw"), SearchVectorConfig("remarkabilities__label", "raw"), SearchVectorConfig("technical_processes__label", "raw"), @@ -2089,6 +2209,8 @@ class Find( ] HISTORICAL_M2M = [ "material_types", + "iconographic_patterns", + "workshop_movement_styles", "technical_processes", "periods", "datings", @@ -2117,6 +2239,8 @@ class Find( "cultural_attributions", "functional_areas", "material_types", + "iconographic_patterns", + "workshop_movement_styles", "integrities", "recommended_treatments", "museum_former_collections", @@ -2175,6 +2299,7 @@ class Find( order = models.IntegerField(_("Order"), default=1) label = models.TextField(_("Free ID")) denomination = models.TextField(_("Denomination"), blank=True, default="") + title = models.TextField(_("Title"), blank=True, default="") # museum module IDs museum_id_prefix = models.TextField(_("Museum ID prefix"), blank=True, default="") museum_id = models.TextField(_("Museum inventory number"), blank=True, default="") @@ -2184,6 +2309,21 @@ class Find( description = models.TextField(_("Description"), blank=True, default="") decoration = models.TextField(_("Decoration"), blank=True, default="") inscription = models.TextField(_("Inscription"), blank=True, default="") + comparanda = models.TextField(_("Comparanda"), blank=True, default="") + iconographic_patterns = models.ManyToManyField( + IconographicPatternType, + verbose_name=_("Iconographic patterns"), + related_name="finds", + blank=True, + ) + iconography_notes = models.TextField(_("Notes on iconography"), blank=True, + default="") + workshop_movement_styles = models.ManyToManyField( + WorkshopMovementStyleType, + verbose_name=_("Workshop, movement, style"), + related_name="finds", + blank=True, + ) manufacturing_place = models.TextField( _("Manufacturing place"), blank=True, default="" ) @@ -2242,6 +2382,28 @@ class Find( cultural_attributions = models.ManyToManyField( CulturalAttributionType, verbose_name=_("Cultural attribution"), blank=True ) + actors = models.ManyToManyField( + QualifiedBiographicalNote, related_name="finds", verbose_name=_("Actors"), + blank=True + ) + ## listed building + listed_building_id = models.TextField( + _("Listed building ID"), default="", blank=True, + ) + listed_building_protection_nature = models.ForeignKey( + ListedBuildingProtectionNature, + verbose_name=_("Nature of listed buildings protection"), + blank=True, + null=True, + related_name="finds", + on_delete=models.SET_NULL, + ) + listed_building_date = models.DateField( + _("Date of listing as a listed building"), blank=True, null=True) + listed_building_notes = models.TextField( + _("Notes on listed building"), default="", blank=True, + ) + ## containers container = models.ForeignKey( "archaeological_warehouse.Container", verbose_name=_("Container"), @@ -2326,7 +2488,8 @@ class Find( dimensions_comment = models.TextField( _("Dimensions comment"), blank=True, default="" ) - mark = models.TextField(_("Mark"), blank=True, default="") + mark_text = models.TextField(_("Transcription of the marking"), blank=True, default="") + mark = models.TextField(_("Marking details"), blank=True, default="") comment = models.TextField(_("General comment"), blank=True, default="") dating_comment = models.TextField(_("Comment on dating"), blank=True, default="") previous_id = models.TextField(_("Previous ID"), blank=True, default="") @@ -2423,6 +2586,9 @@ class Find( verbose_name=_("Conservatory states"), blank=True, ) + conservatory_states_details = models.TextField( + _("Conservatory state details"), blank=True, default="" + ) conservatory_comment = models.TextField( _("Conservatory comment"), blank=True, default="" ) @@ -2556,16 +2722,55 @@ class Find( ] ) + def _has_section(self, name, attrs): + """ + For sheets: evaluate availability of a section. + Cache is set. + """ + if getattr(self, "_cache_section", None) is None: + self._cache_section = {} + if name in self._cache_section: + return self._cache_section[name] + has_value = False + for attr in attrs: + if getattr(self, attr): + has_value = True + break + self._cache_section[name] = has_value + return self._cache_section[name] + + @property + def has_listed_building_section(self): + attrs = ["listed_building_protection_nature_id", "listed_building_id", + "listed_building_notes", "listed_building_date"] + return self._has_section("has_listed_building_section", attrs) + + @property + def has_preservation_fields(self): + attrs = [ + "integrities_count", "remarkabilities_count", "conservatory_states_count", + "conservatory_comment", "alterations_count", "alteration_causes_count", + "recommended_treatments_count", "appraisal_date", "treatment_emergency", + "insurance_value", "estimated_value", "conservatory_states_details" + ] + return self._has_section("has_preservation_fields", attrs) + @property def has_museum_section(self): - if get_current_profile().museum and self.mark: + if getattr(self, "_has_museum_section", None) is not None: + return self._has_museum_section + if self.mark or self.mark_text: + self._has_museum_section = True return True for field in self._meta.get_fields(): - if not field.name.startswith("museum_"): + if not field.name.startswith("museum_") and \ + not field.name.startswith("iconograph"): continue instanced_field = getattr(self, field.name) if instanced_field and (not field.many_to_many or instanced_field.count()): + self._has_museum_section = True return True + self._has_museum_section = False return False @property @@ -2574,7 +2779,6 @@ class Find( @property def museum_entry_date_label(self): - from django.utils.formats import date_format if not self.museum_entry_date: return if self.museum_entry_date and self.museum_entry_date_end and ( @@ -2583,9 +2787,12 @@ class Find( self.museum_entry_date.day == 1 and self.museum_entry_date_end.day == 31 ): return self.museum_entry_date.year - dates = [date_format(self.museum_entry_date, format='SHORT_DATE_FORMAT', use_l10n=True)] + dates = [date_format(self.museum_entry_date, format='SHORT_DATE_FORMAT', + use_l10n=True)] if self.museum_entry_date_end: - dates.append(date_format(self.museum_entry_date_end, format='SHORT_DATE_FORMAT', use_l10n=True)) + dates.append( + date_format(self.museum_entry_date_end, format='SHORT_DATE_FORMAT', + use_l10n=True)) return " / ".join(dates) @classmethod @@ -3034,29 +3241,52 @@ class Find( return "" return "{}-{}".format(bf.context_record.operation.get_reference(), self.index) + def _get_count(self, attr): + """ + For sheets: evaluate count of m2m. + Cache is set. + """ + if getattr(self, "_cache_count", None) is None: + self._cache_count = {} + if attr not in self._cache_count: + self._cache_count[attr] = getattr(self, attr).count() + return self._cache_count[attr] + @property def integrities_count(self): - return self.integrities.count() + return self._get_count("integrities") @property def conservatory_states_count(self): - return self.conservatory_states.count() + return self._get_count("conservatory_states") @property def remarkabilities_count(self): - return self.remarkabilities.count() + return self._get_count("remarkabilities") @property def cultural_attributions_count(self): - return self.cultural_attributions.count() + return self._get_count("cultural_attributions") @property def documents_count(self): - return self.documents.count() + return self._get_count("documents") @property def periods_count(self): - return self.periods.count() + return self._get_count("periods") + + @property + def alterations_count(self): + return self._get_count("alterations") + + @property + def alteration_causes_count(self): + return self._get_count("alteration_causes") + + @property + def recommended_treatments_count(self): + return self._get_count("recommended_treatments") @property def operation(self): |
