summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2026-04-06 20:46:23 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2026-04-06 20:46:23 +0200
commit0d0d0c3fd685e82d6dc2357b2caf834b9dc9c764 (patch)
tree87e125fb29bcc85e4c386bd79c7adce4231e4c8f
parent497b4a6e6db09f943cbdfb8bdad4305ea226bedb (diff)
downloadIshtar-0d0d0c3fd685e82d6dc2357b2caf834b9dc9c764.tar.bz2
Ishtar-0d0d0c3fd685e82d6dc2357b2caf834b9dc9c764.zip
✨ sites - relations between finds: models, migrations, admin
-rw-r--r--archaeological_finds/admin.py8
-rw-r--r--archaeological_finds/migrations/0150_findrelationtype_findrecordrelations.py58
-rw-r--r--archaeological_finds/models.py4
-rw-r--r--archaeological_finds/models_finds.py45
-rw-r--r--archaeological_operations/admin.py1
5 files changed, 112 insertions, 4 deletions
diff --git a/archaeological_finds/admin.py b/archaeological_finds/admin.py
index 555ef8821..ff01cb106 100644
--- a/archaeological_finds/admin.py
+++ b/archaeological_finds/admin.py
@@ -20,7 +20,9 @@
from django.contrib import admin
from ishtar_common.apps import admin_site
-from ishtar_common.admin import HistorizedObjectAdmin, GeneralTypeAdmin, MainGeoDataItem
+from ishtar_common.admin import GeneralTypeAdmin, HistorizedObjectAdmin, MainGeoDataItem
+from archaeological_operations.admin import RecordRelationsAdmin, RelationTypeAdmin
+
from . import models
@@ -242,6 +244,10 @@ class TreatmentStatusAdmin(GeneralTypeAdmin):
extra_list_display = ["order"]
+admin_site.register(models.FindRelationType, RelationTypeAdmin)
+admin_site.register(models.FindRecordRelations, RecordRelationsAdmin)
+
+
@admin.register(models.Exhibition, site=admin_site)
class ExhibitionAdmin(HistorizedObjectAdmin):
list_display = ('name', 'year', 'reference', 'exhibition_type')
diff --git a/archaeological_finds/migrations/0150_findrelationtype_findrecordrelations.py b/archaeological_finds/migrations/0150_findrelationtype_findrecordrelations.py
new file mode 100644
index 000000000..a7be6cc8b
--- /dev/null
+++ b/archaeological_finds/migrations/0150_findrelationtype_findrecordrelations.py
@@ -0,0 +1,58 @@
+# Generated by Django 4.2.21 on 2026-04-06 18:14
+
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+import ishtar_common.models_common
+import re
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('ishtar_common', '0277_data_migration_qualifiedbionotetype'),
+ ('archaeological_finds', '0149_add_editors'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='FindRelationType',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('label', models.TextField(verbose_name='Label')),
+ ('txt_idx', models.TextField(help_text='The slug is the standardized version of the name. It contains only lowercase letters, numbers and hyphens. Each slug must be unique.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), 'Enter a valid “slug” consisting of letters, numbers, underscores or hyphens.', 'invalid')], verbose_name='Textual ID')),
+ ('comment', models.TextField(blank=True, default='', verbose_name='Comment')),
+ ('available', models.BooleanField(default=True, verbose_name='Available')),
+ ('order', models.IntegerField(default=1, verbose_name='Order')),
+ ('symmetrical', models.BooleanField(verbose_name='Symmetrical')),
+ ('tiny_label', models.CharField(blank=True, max_length=50, null=True, verbose_name='Tiny label')),
+ ('logical_relation', models.CharField(blank=True, choices=[('above', 'Above'), ('below', 'Below'), ('equal', 'Equal'), ('include', 'Include'), ('included', 'Is included')], max_length=10, null=True, verbose_name='Logical relation')),
+ ('inverse_relation', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='archaeological_finds.findrelationtype', verbose_name='Inverse relation')),
+ ],
+ options={
+ 'verbose_name': 'Find relation type',
+ 'verbose_name_plural': 'Find relation types',
+ 'ordering': ('order', 'label'),
+ },
+ bases=(ishtar_common.models_common.Cached, models.Model),
+ ),
+ migrations.CreateModel(
+ name='FindRecordRelations',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('timestamp_geo', models.IntegerField(blank=True, null=True, verbose_name='Timestamp geo')),
+ ('timestamp_label', models.IntegerField(blank=True, null=True, verbose_name='Timestamp label')),
+ ('imports', models.ManyToManyField(blank=True, related_name='imported_%(app_label)s_%(class)s', to='ishtar_common.import', verbose_name='Created by imports')),
+ ('imports_updated', models.ManyToManyField(blank=True, related_name='import_updated_%(app_label)s_%(class)s', to='ishtar_common.import', verbose_name='Updated by imports')),
+ ('left_record', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='right_relations', to='archaeological_finds.find')),
+ ('relation_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='archaeological_finds.findrelationtype')),
+ ('right_record', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='left_relations', to='archaeological_finds.find')),
+ ],
+ options={
+ 'verbose_name': 'Find record relation',
+ 'verbose_name_plural': 'Find record relations',
+ 'ordering': ('left_record__cached_label', 'relation_type', 'right_record__cached_label'),
+ 'permissions': [('view_findrelation', 'Can view all Find relations')],
+ },
+ ),
+ ]
diff --git a/archaeological_finds/models.py b/archaeological_finds/models.py
index d79369711..2527a4c83 100644
--- a/archaeological_finds/models.py
+++ b/archaeological_finds/models.py
@@ -14,6 +14,8 @@ from archaeological_finds.models_finds import (
FindBasket,
FindDating,
FindInsideContainer,
+ FindRecordRelations,
+ FindRelationType,
FindTreatment,
FirstBaseFindView,
FunctionalArea,
@@ -78,6 +80,8 @@ __all__ = [
"FindDownstreamTreatments",
"FindInsideContainer",
"FindNonModifTreatments",
+ "FindRecordRelations",
+ "FindRelationType",
"FindTreatment",
"FindTreatments",
"FindUpstreamTreatments",
diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py
index 7e33150ce..99ad1b1ea 100644
--- a/archaeological_finds/models_finds.py
+++ b/archaeological_finds/models_finds.py
@@ -54,26 +54,30 @@ from ishtar_common.models import (
Document,
DocumentItem,
document_attached_changed,
+ GeneralRecordRelations,
+ GeneralRelationType,
GeneralType,
GeoItem,
+ geo_item_pre_delete,
get_current_profile,
HierarchicalType,
HistoryModel,
Imported,
IshtarSiteProfile,
LightHistorizedItem,
+ main_item_pre_delete,
MainItem,
OrderedHierarchicalType,
OrderedType,
Organization,
OwnPerms,
Person,
+ post_delete_record_relation,
post_save_cache,
QuickAction,
+ RecordRelationManager,
SearchVectorConfig,
ValueGetter,
- main_item_pre_delete,
- geo_item_pre_delete
)
from ishtar_common.models_common import HistoricalRecords, SerializeItem, \
GeoVectorData, geodata_attached_changed
@@ -3943,10 +3947,45 @@ def base_find_find_changed(sender, **kwargs):
m2m_changed.connect(base_find_find_changed, sender=Find.base_finds.through)
-
m2m_changed.connect(document_attached_changed, sender=Find.documents.through)
+class FindRelationType(GeneralRelationType):
+ ADMIN_SECTION = _("Finds")
+ class Meta:
+ verbose_name = _("Find relation type")
+ verbose_name_plural = _("Find relation types")
+ ordering = ("order", "label")
+
+
+class FindRecordRelations(GeneralRecordRelations):
+ ADMIN_SECTION = _("Finds")
+ MAIN_ATTR = "left_record"
+ left_record = models.ForeignKey(
+ Find, related_name="right_relations", on_delete=models.CASCADE
+ )
+ right_record = models.ForeignKey(
+ Find, related_name="left_relations", on_delete=models.CASCADE
+ )
+ relation_type = models.ForeignKey(FindRelationType, on_delete=models.PROTECT)
+ objects = RecordRelationManager()
+
+ class Meta:
+ verbose_name = _("Find record relation")
+ verbose_name_plural = _("Find record relations")
+ ordering = (
+ "left_record__cached_label",
+ "relation_type",
+ "right_record__cached_label",
+ )
+ permissions = [
+ ("view_findrelation", "Can view all Find relations"),
+ ]
+
+
+post_delete.connect(post_delete_record_relation, sender=FindRecordRelations)
+
+
class FindDating(BaseDating):
SERIALIZE_EXCLUDE = ["find"]
CURRENT_MODEL = Find
diff --git a/archaeological_operations/admin.py b/archaeological_operations/admin.py
index 8d08696ea..82c5c7f90 100644
--- a/archaeological_operations/admin.py
+++ b/archaeological_operations/admin.py
@@ -141,6 +141,7 @@ class RecordRelationsAdmin(admin.ModelAdmin):
admin_site.register(models.RecordRelations, RecordRelationsAdmin)
+admin_site.register(models.SiteRecordRelations, RecordRelationsAdmin)
class RelationTypeAdmin(GeneralTypeAdmin):