diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2023-01-30 18:57:24 +0100 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2023-02-02 17:40:14 +0100 |
commit | da9baba079fd8ac3ca939c2a8e4f7fd889d9c0ca (patch) | |
tree | f703963dcb757ba0a067129d4c8a8287009b96a5 | |
parent | b6a58ae42723a93df08dca35646b6f5ea1270d49 (diff) | |
download | Ishtar-da9baba079fd8ac3ca939c2a8e4f7fd889d9c0ca.tar.bz2 Ishtar-da9baba079fd8ac3ca939c2a8e4f7fd889d9c0ca.zip |
Model: add history for document and containers
-rw-r--r-- | CHANGES.md | 1 | ||||
-rw-r--r-- | archaeological_warehouse/admin.py | 1 | ||||
-rw-r--r-- | archaeological_warehouse/migrations/0116_auto_20230130_1605.py | 44 | ||||
-rw-r--r-- | archaeological_warehouse/migrations/0116_auto_20230202_1633.py | 125 | ||||
-rw-r--r-- | archaeological_warehouse/migrations/0117_migrate_created.py | 15 | ||||
-rw-r--r-- | archaeological_warehouse/models.py | 13 | ||||
-rw-r--r-- | ishtar_common/migrations/0224_auto_20230130_1604.py | 94 | ||||
-rw-r--r-- | ishtar_common/migrations/0224_auto_20230130_1838.py | 165 | ||||
-rw-r--r-- | ishtar_common/migrations/0225_migrate_created.py | 2 | ||||
-rw-r--r-- | ishtar_common/models.py | 2 |
10 files changed, 315 insertions, 147 deletions
diff --git a/CHANGES.md b/CHANGES.md index 78b175631..7c3be65cc 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,7 @@ Ishtar changelog - add custom cached_label configuration for each main item - sheet document: better UI for files - add "created" field on main items in order to facilitate queries +- model: add history for document and containers ### Bug fixes ### - find form: remove TAQ/TPQ check diff --git a/archaeological_warehouse/admin.py b/archaeological_warehouse/admin.py index 6dd6ffde6..d2ccbb31f 100644 --- a/archaeological_warehouse/admin.py +++ b/archaeological_warehouse/admin.py @@ -77,7 +77,6 @@ class ContainerAdmin(HistorizedObjectAdmin, MainGeoDataItem): search_fields = ("reference", "container_type", "cached_label", "responsible") model = models.Container readonly_fields = HistorizedObjectAdmin.readonly_fields + [ - "history_date", "merge_key", "merge_exclusion", "merge_candidate", diff --git a/archaeological_warehouse/migrations/0116_auto_20230130_1605.py b/archaeological_warehouse/migrations/0116_auto_20230130_1605.py deleted file mode 100644 index bb25b02bd..000000000 --- a/archaeological_warehouse/migrations/0116_auto_20230130_1605.py +++ /dev/null @@ -1,44 +0,0 @@ -# Generated by Django 2.2.24 on 2023-01-30 16:05 - -import datetime -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('archaeological_warehouse', '0115_auto_20230120_1133'), - ] - - operations = [ - migrations.AddField( - model_name='container', - name='created', - field=models.DateTimeField(blank=True, default=datetime.datetime.now), - ), - migrations.AddField( - model_name='historicalwarehouse', - name='cached_label', - field=models.TextField(blank=True, db_index=True, default='', help_text='Generated automatically - do not edit', verbose_name='Cached name'), - ), - migrations.AddField( - model_name='historicalwarehouse', - name='created', - field=models.DateTimeField(blank=True, default=datetime.datetime.now), - ), - migrations.AddField( - model_name='warehouse', - name='cached_label', - field=models.TextField(blank=True, db_index=True, default='', help_text='Generated automatically - do not edit', verbose_name='Cached name'), - ), - migrations.AddField( - model_name='warehouse', - name='created', - field=models.DateTimeField(blank=True, default=datetime.datetime.now), - ), - migrations.AlterField( - model_name='container', - name='cached_label', - field=models.TextField(blank=True, db_index=True, default='', help_text='Generated automatically - do not edit', verbose_name='Cached name'), - ), - ] diff --git a/archaeological_warehouse/migrations/0116_auto_20230202_1633.py b/archaeological_warehouse/migrations/0116_auto_20230202_1633.py new file mode 100644 index 000000000..657f950c4 --- /dev/null +++ b/archaeological_warehouse/migrations/0116_auto_20230202_1633.py @@ -0,0 +1,125 @@ +# Generated by Django 2.2.24 on 2023-02-02 16:33 + +import datetime +from django.conf import settings +import django.contrib.gis.db.models.fields +import django.contrib.postgres.fields.jsonb +import django.contrib.postgres.search +from django.db import migrations, models +import django.db.models.deletion +import simple_history.models +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('ishtar_common', '0225_migrate_created'), + ('archaeological_warehouse', '0115_auto_20230120_1133'), + ] + + operations = [ + migrations.RenameField( + model_name='container', + old_name='history_date', + new_name='history_date_deprecated', + ), + migrations.AddField( + model_name='container', + name='created', + field=models.DateTimeField(blank=True, default=datetime.datetime.now), + ), + migrations.AddField( + model_name='historicalwarehouse', + name='cached_label', + field=models.TextField(blank=True, db_index=True, default='', help_text='Generated automatically - do not edit', verbose_name='Cached name'), + ), + migrations.AddField( + model_name='historicalwarehouse', + name='created', + field=models.DateTimeField(blank=True, default=datetime.datetime.now), + ), + migrations.AddField( + model_name='warehouse', + name='cached_label', + field=models.TextField(blank=True, db_index=True, default='', help_text='Generated automatically - do not edit', verbose_name='Cached name'), + ), + migrations.AddField( + model_name='warehouse', + name='created', + field=models.DateTimeField(blank=True, default=datetime.datetime.now), + ), + migrations.AlterField( + model_name='container', + name='cached_label', + field=models.TextField(blank=True, db_index=True, default='', help_text='Generated automatically - do not edit', verbose_name='Cached name'), + ), + migrations.CreateModel( + name='HistoricalContainer', + fields=[ + ('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')), + ('search_vector', django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto filled at save', null=True, verbose_name='Search vector')), + ('data', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict)), + ('last_modified', models.DateTimeField(blank=True, default=datetime.datetime.now)), + ('created', models.DateTimeField(blank=True, default=datetime.datetime.now)), + ('history_m2m', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict)), + ('need_update', models.BooleanField(default=False, verbose_name='Need update')), + ('locked', models.BooleanField(default=False, verbose_name='Item locked for edition')), + ('merge_key', models.TextField(blank=True, null=True, verbose_name='Merge key')), + ('archived', models.NullBooleanField(default=False)), + ('x', models.FloatField(blank=True, null=True, verbose_name='X')), + ('y', models.FloatField(blank=True, null=True, verbose_name='Y')), + ('z', models.FloatField(blank=True, null=True, verbose_name='Z')), + ('estimated_error_x', models.FloatField(blank=True, null=True, verbose_name='Estimated error for X')), + ('estimated_error_y', models.FloatField(blank=True, null=True, verbose_name='Estimated error for Y')), + ('estimated_error_z', models.FloatField(blank=True, null=True, verbose_name='Estimated error for Z')), + ('point', django.contrib.gis.db.models.fields.PointField(blank=True, dim=3, null=True, srid=4326, verbose_name='Point')), + ('point_2d', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326, verbose_name='Point (2D)')), + ('point_source', models.CharField(blank=True, choices=[('T', 'Town'), ('P', 'Precise'), ('M', 'Polygon')], max_length=1, null=True, verbose_name='Point source')), + ('point_source_item', models.CharField(blank=True, max_length=100, null=True, verbose_name='Point source item')), + ('multi_polygon', django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326, verbose_name='Multi polygon')), + ('multi_polygon_source', models.CharField(blank=True, choices=[('T', 'Town'), ('P', 'Precise'), ('M', 'Polygon')], max_length=1, null=True, verbose_name='Multi-polygon source')), + ('multi_polygon_source_item', models.CharField(blank=True, max_length=100, null=True, verbose_name='Multi polygon source item')), + ('cached_label', models.TextField(blank=True, db_index=True, default='', help_text='Generated automatically - do not edit', verbose_name='Cached name')), + ('complete_identifier', models.TextField(blank=True, default='', verbose_name='Complete identifier')), + ('custom_index', models.IntegerField(blank=True, null=True, verbose_name='Custom index')), + ('qrcode', models.TextField(blank=True, max_length=255, null=True)), + ('uuid', models.UUIDField(default=uuid.uuid4)), + ('reference', models.TextField(verbose_name='Container ref.')), + ('comment', models.TextField(blank=True, default='', verbose_name='Comment')), + ('cached_location', models.TextField(blank=True, db_index=True, default='', verbose_name='Cached location')), + ('cached_division', models.TextField(blank=True, db_index=True, default='', verbose_name='Cached division')), + ('index', models.IntegerField(blank=True, db_index=True, null=True, verbose_name='Container ID')), + ('weight', models.FloatField(blank=True, null=True, verbose_name='Measured weight (g)')), + ('calculated_weight', models.FloatField(blank=True, null=True, verbose_name='Calculated weight (g)')), + ('cached_weight', models.FloatField(blank=True, help_text='Entered weight if available otherwise calculated weight.', null=True, verbose_name='Cached weight (g)')), + ('old_reference', models.TextField(blank=True, default='', verbose_name='Old reference')), + ('external_id', models.TextField(blank=True, default='', verbose_name='External ID')), + ('auto_external_id', models.BooleanField(default=False, verbose_name='External ID is set automatically')), + ('history_date_deprecated', models.DateTimeField(default=datetime.datetime.now)), + ('history_id', models.AutoField(primary_key=True, serialize=False)), + ('history_date', models.DateTimeField()), + ('history_change_reason', models.CharField(max_length=100, null=True)), + ('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)), + ('container_type', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='archaeological_warehouse.ContainerType', verbose_name='Container type')), + ('history_creator', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Creator')), + ('history_modifier', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Last editor')), + ('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)), + ('location', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='archaeological_warehouse.Warehouse', verbose_name='Location (warehouse)')), + ('lock_user', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Locked by')), + ('main_geodata', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='ishtar_common.GeoVectorData', verbose_name='Main geodata')), + ('main_image', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='ishtar_common.Document', verbose_name='Main image')), + ('parent', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='archaeological_warehouse.Container', verbose_name='Parent container')), + ('responsibility', models.ForeignKey(blank=True, db_constraint=False, help_text='Warehouse that owns the container', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='archaeological_warehouse.Warehouse', verbose_name='Responsibility')), + ('responsible', models.ForeignKey(blank=True, db_constraint=False, help_text='Deprecated - do not use', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='archaeological_warehouse.Warehouse', verbose_name='Responsible warehouse')), + ('spatial_reference_system', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='ishtar_common.SpatialReferenceSystem', verbose_name='Spatial Reference System')), + ], + options={ + 'verbose_name': 'historical Container', + 'ordering': ('-history_date', '-history_id'), + 'get_latest_by': 'history_date', + }, + bases=(simple_history.models.HistoricalChanges, models.Model), + ), + ] diff --git a/archaeological_warehouse/migrations/0117_migrate_created.py b/archaeological_warehouse/migrations/0117_migrate_created.py index 0c9962a59..8bf125627 100644 --- a/archaeological_warehouse/migrations/0117_migrate_created.py +++ b/archaeological_warehouse/migrations/0117_migrate_created.py @@ -13,12 +13,23 @@ def migrate_created(apps, __): migrate_created_field(apps, app_name, model_names) +def migrate_history_date(apps, __): + app_name = "archaeological_warehouse" + model_name = "Container" + model = apps.get_model(app_name, model_name) + for item in model.objects.all(): + item.created = item.history_date_deprecated + item.skip_history_when_saving = True + item.save() + + class Migration(migrations.Migration): dependencies = [ - ('archaeological_warehouse', '0116_auto_20230130_1605'), + ('archaeological_warehouse', '0116_auto_20230202_1633'), ] operations = [ - migrations.RunPython(migrate_created) + migrations.RunPython(migrate_created), + migrations.RunPython(migrate_history_date) ] diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py index 224fe8b21..00500bdcf 100644 --- a/archaeological_warehouse/models.py +++ b/archaeological_warehouse/models.py @@ -34,10 +34,11 @@ from ishtar_common.utils import ugettext_lazy as _, pgettext_lazy from django.apps import apps from ishtar_common.data_importer import post_importer_action, pre_importer_action from ishtar_common.model_managers import ExternalIdManager, UUIDModelManager -from ishtar_common.models import ValueGetter, get_current_profile +from ishtar_common.models import ValueGetter, get_current_profile, HistoryModel from ishtar_common.models_common import ( GeneralType, - LightHistorizedItem, + BaseHistorizedItem, + HistoricalRecords, OwnPerms, Address, post_save_cache, @@ -834,7 +835,7 @@ class ContainerTree(models.Model): class Container( DocumentItem, Merge, - LightHistorizedItem, + BaseHistorizedItem, CompleteIdentifierItem, GeoItem, OwnPerms, @@ -1047,10 +1048,10 @@ class Container( "documents__associated_file__isnull", "documents__associated_url__isnull", ] - BOOL_FIELDS = LightHistorizedItem.BOOL_FIELDS + ["container_type__stationary"] + BOOL_FIELDS = BaseHistorizedItem.BOOL_FIELDS + ["container_type__stationary"] REVERSED_MANY_COUNTED_FIELDS = ["finds__isnull", "finds_ref"] - ALT_NAMES.update(LightHistorizedItem.ALT_NAMES) + ALT_NAMES.update(BaseHistorizedItem.ALT_NAMES) ALT_NAMES.update(DocumentItem.ALT_NAMES) DYNAMIC_REQUESTS = { @@ -1167,6 +1168,8 @@ class Container( blank=True, null=True, ) + history_date_deprecated = models.DateTimeField(default=datetime.datetime.now) + history = HistoricalRecords(bases=[HistoryModel]) DISABLE_POLYGONS = False MERGE_ATTRIBUTE = "get_merge_key" diff --git a/ishtar_common/migrations/0224_auto_20230130_1604.py b/ishtar_common/migrations/0224_auto_20230130_1604.py deleted file mode 100644 index 524caae16..000000000 --- a/ishtar_common/migrations/0224_auto_20230130_1604.py +++ /dev/null @@ -1,94 +0,0 @@ -# Generated by Django 2.2.24 on 2023-01-30 16:04 - -import datetime -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('ishtar_common', '0223_auto_20230120_1124'), - ] - - operations = [ - migrations.AddField( - model_name='document', - name='cached_label', - field=models.TextField(blank=True, db_index=True, default='', help_text='Generated automatically - do not edit', verbose_name='Cached name'), - ), - migrations.AddField( - model_name='document', - name='created', - field=models.DateTimeField(blank=True, default=datetime.datetime.now), - ), - migrations.AddField( - model_name='historicalorganization', - name='created', - field=models.DateTimeField(blank=True, default=datetime.datetime.now), - ), - migrations.AddField( - model_name='historicalperson', - name='created', - field=models.DateTimeField(blank=True, default=datetime.datetime.now), - ), - migrations.AddField( - model_name='ishtarsiteprofile', - name='basefind_cached_label', - field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='Base find cached label'), - ), - migrations.AddField( - model_name='ishtarsiteprofile', - name='container_cached_label', - field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='Container cached label'), - ), - migrations.AddField( - model_name='ishtarsiteprofile', - name='contextrecord_cached_label', - field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='Context record cached label'), - ), - migrations.AddField( - model_name='ishtarsiteprofile', - name='document_cached_label', - field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='Document cached label'), - ), - migrations.AddField( - model_name='ishtarsiteprofile', - name='file_cached_label', - field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='File cached label'), - ), - migrations.AddField( - model_name='ishtarsiteprofile', - name='find_cached_label', - field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='Find cached label'), - ), - migrations.AddField( - model_name='ishtarsiteprofile', - name='operation_cached_label', - field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='Operation cached label'), - ), - migrations.AddField( - model_name='ishtarsiteprofile', - name='parcel_cached_label', - field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='Parcel cached label'), - ), - migrations.AddField( - model_name='ishtarsiteprofile', - name='site_cached_label', - field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='Site cached label'), - ), - migrations.AddField( - model_name='ishtarsiteprofile', - name='warehouse_cached_label', - field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='Warehouse cached label'), - ), - migrations.AddField( - model_name='organization', - name='created', - field=models.DateTimeField(blank=True, default=datetime.datetime.now), - ), - migrations.AddField( - model_name='person', - name='created', - field=models.DateTimeField(blank=True, default=datetime.datetime.now), - ), - ] diff --git a/ishtar_common/migrations/0224_auto_20230130_1838.py b/ishtar_common/migrations/0224_auto_20230130_1838.py new file mode 100644 index 000000000..749d48725 --- /dev/null +++ b/ishtar_common/migrations/0224_auto_20230130_1838.py @@ -0,0 +1,165 @@ +# Generated by Django 2.2.24 on 2023-01-30 18:38 + +import datetime +from django.conf import settings +import django.contrib.postgres.fields.jsonb +import django.contrib.postgres.search +from django.db import migrations, models +import django.db.models.deletion +import simple_history.models + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('ishtar_common', '0223_auto_20230120_1124'), + ] + + operations = [ + migrations.AddField( + model_name='document', + name='cached_label', + field=models.TextField(blank=True, db_index=True, default='', help_text='Generated automatically - do not edit', verbose_name='Cached name'), + ), + migrations.AddField( + model_name='document', + name='created', + field=models.DateTimeField(blank=True, default=datetime.datetime.now), + ), + migrations.AddField( + model_name='historicalorganization', + name='created', + field=models.DateTimeField(blank=True, default=datetime.datetime.now), + ), + migrations.AddField( + model_name='historicalperson', + name='created', + field=models.DateTimeField(blank=True, default=datetime.datetime.now), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='basefind_cached_label', + field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='Base find cached label'), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='container_cached_label', + field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='Container cached label'), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='contextrecord_cached_label', + field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='Context record cached label'), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='document_cached_label', + field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='Document cached label'), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='file_cached_label', + field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='File cached label'), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='find_cached_label', + field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='Find cached label'), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='operation_cached_label', + field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='Operation cached label'), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='parcel_cached_label', + field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='Parcel cached label'), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='site_cached_label', + field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='Site cached label'), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='warehouse_cached_label', + field=models.TextField(blank=True, default='', help_text='Formula to manage cached label. If not set a default is provided', verbose_name='Warehouse cached label'), + ), + migrations.AddField( + model_name='organization', + name='created', + field=models.DateTimeField(blank=True, default=datetime.datetime.now), + ), + migrations.AddField( + model_name='person', + name='created', + field=models.DateTimeField(blank=True, default=datetime.datetime.now), + ), + migrations.CreateModel( + name='HistoricalDocument', + fields=[ + ('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')), + ('search_vector', django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto filled at save', null=True, verbose_name='Search vector')), + ('data', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict)), + ('last_modified', models.DateTimeField(blank=True, default=datetime.datetime.now)), + ('created', models.DateTimeField(blank=True, default=datetime.datetime.now)), + ('history_m2m', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict)), + ('need_update', models.BooleanField(default=False, verbose_name='Need update')), + ('locked', models.BooleanField(default=False, verbose_name='Item locked for edition')), + ('cached_label', models.TextField(blank=True, db_index=True, default='', help_text='Generated automatically - do not edit', verbose_name='Cached name')), + ('complete_identifier', models.TextField(blank=True, default='', verbose_name='Complete identifier')), + ('custom_index', models.IntegerField(blank=True, null=True, verbose_name='Custom index')), + ('qrcode', models.TextField(blank=True, max_length=255, null=True)), + ('image', models.TextField(blank=True, help_text='La taille maximale supportée pour le fichier est de 100 Mo.', max_length=255, null=True)), + ('thumbnail', models.TextField(blank=True, help_text='La taille maximale supportée pour le fichier est de 100 Mo.', max_length=255, null=True)), + ('title', models.TextField(blank=True, default='', verbose_name='Title')), + ('associated_file', models.TextField(blank=True, help_text='La taille maximale supportée pour le fichier est de 100 Mo.', max_length=255, null=True, verbose_name='Associated file')), + ('index', models.IntegerField(blank=True, null=True, verbose_name='Index')), + ('external_id', models.TextField(blank=True, default='', verbose_name='External ID')), + ('reference', models.TextField(blank=True, default='', verbose_name='Ref.')), + ('internal_reference', models.TextField(blank=True, default='', verbose_name='Internal ref.')), + ('publishing_year', models.PositiveIntegerField(blank=True, null=True, verbose_name='Year of publication')), + ('issn', models.CharField(blank=True, max_length=10, null=True, verbose_name='ISSN')), + ('isbn', models.CharField(blank=True, max_length=17, null=True, verbose_name='ISBN')), + ('source_free_input', models.CharField(blank=True, max_length=500, null=True, verbose_name='Source - free input')), + ('source_page_range', models.CharField(blank=True, max_length=500, null=True, verbose_name='Source - page range')), + ('scale', models.CharField(blank=True, max_length=30, null=True, verbose_name='Scale')), + ('authors_raw', models.CharField(blank=True, max_length=250, null=True, verbose_name='Authors (raw)')), + ('associated_url', models.URLField(blank=True, max_length=1000, null=True, verbose_name='Numerical ressource (web address)')), + ('receipt_date', models.DateField(blank=True, null=True, verbose_name='Receipt date')), + ('creation_date', models.DateField(blank=True, null=True, verbose_name='Creation date')), + ('receipt_date_in_documentation', models.DateField(blank=True, null=True, verbose_name='Receipt date in documentation')), + ('item_number', models.IntegerField(default=1, verbose_name='Number of items')), + ('description', models.TextField(blank=True, default='', verbose_name='Description')), + ('container_id', models.PositiveIntegerField(blank=True, null=True, verbose_name='Container ID')), + ('container_ref_id', models.PositiveIntegerField(blank=True, null=True, verbose_name='Container ID')), + ('comment', models.TextField(blank=True, default='', verbose_name='Comment')), + ('additional_information', models.TextField(blank=True, default='', verbose_name='Additional information')), + ('duplicate', models.NullBooleanField(verbose_name='Has a duplicate')), + ('associated_links', models.TextField(blank=True, default='', verbose_name='Symbolic links')), + ('cache_related_label', models.TextField(blank=True, db_index=True, default='', help_text='Cached value - do not edit', verbose_name='Related')), + ('history_id', models.AutoField(primary_key=True, serialize=False)), + ('history_date', models.DateTimeField()), + ('history_change_reason', models.CharField(max_length=100, null=True)), + ('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)), + ('format_type', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='ishtar_common.Format', verbose_name='Format')), + ('history_creator', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Creator')), + ('history_modifier', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Last editor')), + ('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)), + ('language', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='ishtar_common.Language', verbose_name='Language')), + ('lock_user', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Locked by')), + ('publisher', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='ishtar_common.Organization', verbose_name='Publisher')), + ('source', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='ishtar_common.Document', verbose_name='Source')), + ('source_type', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='ishtar_common.SourceType', verbose_name='Type')), + ('support_type', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='ishtar_common.SupportType', verbose_name='Medium')), + ], + options={ + 'verbose_name': 'historical Document', + 'ordering': ('-history_date', '-history_id'), + 'get_latest_by': 'history_date', + }, + bases=(simple_history.models.HistoricalChanges, models.Model), + ), + ] diff --git a/ishtar_common/migrations/0225_migrate_created.py b/ishtar_common/migrations/0225_migrate_created.py index 1304e8b92..554df7309 100644 --- a/ishtar_common/migrations/0225_migrate_created.py +++ b/ishtar_common/migrations/0225_migrate_created.py @@ -17,7 +17,7 @@ def migrate_created(apps, __): class Migration(migrations.Migration): dependencies = [ - ('ishtar_common', '0224_auto_20230130_1604'), + ('ishtar_common', '0224_auto_20230130_1838'), ] operations = [ diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 8dd1fc3fe..12cdf01f0 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -133,6 +133,7 @@ from ishtar_common.models_common import ( HierarchicalType, BaseHistorizedItem, LightHistorizedItem, + HistoricalRecords, FullSearch, SearchAltName, OwnPerms, @@ -4268,6 +4269,7 @@ class Document( db_index=True, help_text=_("Cached value - do not edit"), ) + history = HistoricalRecords(inherit=True) class Meta: verbose_name = _("Document") |