summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archaeological_context_records/migrations/0047_auto_20190628_1257.py25
-rw-r--r--archaeological_context_records/models.py1
-rw-r--r--archaeological_files/migrations/0019_auto_20190628_1257.py25
-rw-r--r--archaeological_finds/migrations/0067_auto_20190628_1257.py60
-rw-r--r--archaeological_finds/tests.py46
-rw-r--r--archaeological_operations/migrations/0056_auto_20190628_1257.py55
-rw-r--r--archaeological_operations/models.py3
-rw-r--r--archaeological_warehouse/migrations/0037_auto_20190628_1257.py36
-rw-r--r--archaeological_warehouse/models.py32
-rw-r--r--archaeological_warehouse/tests.py85
-rwxr-xr-xconf/ishtar-pending-update-cron10
-rw-r--r--ishtar_common/management/commands/process_pending_update.py67
-rw-r--r--ishtar_common/migrations/0097_auto_20190628_1256.py40
-rw-r--r--ishtar_common/models.py14
-rw-r--r--ishtar_common/utils.py24
15 files changed, 489 insertions, 34 deletions
diff --git a/archaeological_context_records/migrations/0047_auto_20190628_1257.py b/archaeological_context_records/migrations/0047_auto_20190628_1257.py
new file mode 100644
index 000000000..913eab154
--- /dev/null
+++ b/archaeological_context_records/migrations/0047_auto_20190628_1257.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.18 on 2019-06-28 12:57
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_context_records', '0046_auto_20190528_1048'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='contextrecord',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='historicalcontextrecord',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ ]
diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py
index ace66aed6..1b81f3b63 100644
--- a/archaeological_context_records/models.py
+++ b/archaeological_context_records/models.py
@@ -431,6 +431,7 @@ class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem,
]
CACHED_LABELS = ['cached_label', 'cached_periods',
"cached_related_context_records"]
+ DOWN_MODEL_UPDATE = ["base_finds"]
history = HistoricalRecords(bases=[HistoryModel])
objects = ExternalIdManager()
diff --git a/archaeological_files/migrations/0019_auto_20190628_1257.py b/archaeological_files/migrations/0019_auto_20190628_1257.py
new file mode 100644
index 000000000..d76494330
--- /dev/null
+++ b/archaeological_files/migrations/0019_auto_20190628_1257.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.18 on 2019-06-28 12:57
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_files', '0018_auto_20190206_1522'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='file',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='historicalfile',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ ]
diff --git a/archaeological_finds/migrations/0067_auto_20190628_1257.py b/archaeological_finds/migrations/0067_auto_20190628_1257.py
new file mode 100644
index 000000000..b8122ce4d
--- /dev/null
+++ b/archaeological_finds/migrations/0067_auto_20190628_1257.py
@@ -0,0 +1,60 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.18 on 2019-06-28 12:57
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_finds', '0066_auto_20190527_1811'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='basefind',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='find',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='historicalbasefind',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='historicalfind',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='historicaltreatment',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='historicaltreatmentfile',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='property',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='treatment',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='treatmentfile',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ ]
diff --git a/archaeological_finds/tests.py b/archaeological_finds/tests.py
index acd86727b..3d4d6f1d7 100644
--- a/archaeological_finds/tests.py
+++ b/archaeological_finds/tests.py
@@ -1672,6 +1672,52 @@ class GeomaticTest(FindInit, TestCase):
def setUp(self):
self.create_finds(data_base={"label": u"Find 1"}, force=True)
+ def test_update_container_localisation_on_warehouse_update(self):
+ profile, created = IshtarSiteProfile.objects.get_or_create(
+ slug='default', active=True)
+ profile.mapping = True
+ profile.save()
+ wgs84 = SpatialReferenceSystem.objects.get(srid=4326)
+
+ find = self.finds[0]
+ base_find = find.base_finds.all()[0]
+ self.assertEqual(base_find.x, None)
+
+ operation = Operation.objects.get(
+ pk=base_find.context_record.operation.pk
+ )
+ operation.x, operation.y = 33, 42
+ operation.spatial_reference_system = wgs84
+ operation.save()
+
+ # an update is pending for the linked context record
+ q = ContextRecord.objects.filter(
+ pk=base_find.context_record.pk,
+ need_update=True)
+ self.assertEqual(q.count(), 1)
+
+ # process pending update
+ context_record = q.all()[0]
+ self.assertEqual(context_record.x, None) # update has to be done
+ context_record.skip_history_when_saving = True
+ context_record._no_move = True
+ context_record.save()
+ context_record = ContextRecord.objects.get(pk=context_record.pk)
+ self.assertEqual(context_record.x, 33)
+
+ # then an update is pending for the linked base find
+ q = models.BaseFind.objects.filter(pk=base_find.pk, need_update=True)
+ self.assertEqual(q.count(), 1)
+
+ # process pending update
+ bf = q.all()[0]
+ self.assertEqual(bf.x, None) # update has to be done
+ bf.skip_history_when_saving = True
+ bf._no_move = True
+ bf.save()
+ bf = models.BaseFind.objects.get(pk=bf.pk)
+ self.assertEqual(bf.x, 33)
+
def test_post_save_point(self):
find = self.finds[0]
base_find = find.base_finds.all()[0]
diff --git a/archaeological_operations/migrations/0056_auto_20190628_1257.py b/archaeological_operations/migrations/0056_auto_20190628_1257.py
new file mode 100644
index 000000000..641d1e09f
--- /dev/null
+++ b/archaeological_operations/migrations/0056_auto_20190628_1257.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.18 on 2019-06-28 12:57
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_operations', '0055_auto_20190521_1244'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='administrativeact',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='archaeologicalsite',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='historicaladministrativeact',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='historicalarchaeologicalsite',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='historicaloperation',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='operation',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='parcel',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='parcelowner',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ ]
diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py
index 55e90ec07..95c60e6ff 100644
--- a/archaeological_operations/models.py
+++ b/archaeological_operations/models.py
@@ -254,6 +254,7 @@ class ArchaeologicalSite(DocumentItem, BaseHistorizedItem, QRCodeItem,
HISTORICAL_M2M = ['periods', 'remains', 'towns']
CACHED_LABELS = ['cached_label', 'cached_towns_label', 'cached_periods',
'cached_remains']
+ DOWN_MODEL_UPDATE = ["context_records"]
# objects = SiteManager()
@@ -871,6 +872,8 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem, QRCodeItem,
'towns__numero_insee__startswith': '_get_department_code',
}
+ DOWN_MODEL_UPDATE = ["context_record"]
+
HISTORICAL_M2M = [
'remains', 'towns', 'periods',
]
diff --git a/archaeological_warehouse/migrations/0037_auto_20190628_1257.py b/archaeological_warehouse/migrations/0037_auto_20190628_1257.py
new file mode 100644
index 000000000..82e489a8d
--- /dev/null
+++ b/archaeological_warehouse/migrations/0037_auto_20190628_1257.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.18 on 2019-06-28 12:57
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_warehouse', '0036_auto_20190627_1321'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='collection',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='container',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='warehouse',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='organization',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='warehouses', to='ishtar_common.Organization', verbose_name='Organisation'),
+ ),
+ ]
diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py
index a93a0917d..3dba70355 100644
--- a/archaeological_warehouse/models.py
+++ b/archaeological_warehouse/models.py
@@ -35,7 +35,8 @@ from ishtar_common.models import Document, GeneralType, get_external_id, \
document_attached_changed, SearchAltName, DynamicRequest, GeoItem, \
QRCodeItem, SearchVectorConfig, DocumentItem
from ishtar_common.model_merging import merge_model_objects
-from ishtar_common.utils import cached_label_changed, post_save_geo, task
+from ishtar_common.utils import cached_label_changed, \
+ cached_label_and_geo_changed
class WarehouseType(GeneralType):
@@ -80,6 +81,8 @@ class Warehouse(Address, DocumentItem, GeoItem, QRCodeItem, DashboardFormItem,
),
}
GEO_LABEL = "name"
+ DOWN_MODEL_UPDATE = ["containers"]
+ CACHED_LABELS = []
objects = ExternalIdManager()
@@ -327,30 +330,12 @@ class Warehouse(Address, DocumentItem, GeoItem, QRCodeItem, DashboardFormItem,
self._cached_label_checked = False
self.save()
return
- if not settings.USE_BACKGROUND_TASK:
- update_containers(self)
- else:
- update_containers.delay(self.pk)
-
-
-@task()
-def update_containers(warehouse):
- if not settings.USE_BACKGROUND_TASK:
- for container in warehouse.containers.all():
- cached_label_changed(Container, instance=container)
- return
- try:
- warehouse = Warehouse.objects.get(pk=warehouse)
- except Warehouse.DoesNotExist:
- return
- for container in warehouse.containers.all():
- cached_label_changed(Container, instance=container)
m2m_changed.connect(document_attached_changed,
sender=Warehouse.documents.through)
-post_save.connect(post_save_geo, sender=Warehouse)
+post_save.connect(cached_label_and_geo_changed, sender=Warehouse)
class Collection(LightHistorizedItem):
@@ -875,12 +860,7 @@ class Container(DocumentItem, LightHistorizedItem, QRCodeItem, GeoItem,
loca.delete()
-def container_post_save(sender, **kwargs):
- cached_label_changed(sender=sender, **kwargs)
- post_save_geo(sender=sender, **kwargs)
-
-
-post_save.connect(container_post_save, sender=Container)
+post_save.connect(cached_label_and_geo_changed, sender=Container)
m2m_changed.connect(document_attached_changed,
sender=Container.documents.through)
diff --git a/archaeological_warehouse/tests.py b/archaeological_warehouse/tests.py
index 73cc166ac..3f4df9fad 100644
--- a/archaeological_warehouse/tests.py
+++ b/archaeological_warehouse/tests.py
@@ -17,14 +17,13 @@
# See the file COPYING for details.
-from django.conf import settings
-
from archaeological_finds.tests import FindInit
from ishtar_common.tests import WizardTest, WizardTestFormData as FormData, \
TestCase
from archaeological_finds.tests import WAREHOUSE_FIXTURES
+from ishtar_common.models import IshtarSiteProfile, SpatialReferenceSystem
from archaeological_warehouse import models, views, forms
@@ -189,7 +188,7 @@ class WarehouseTest(TestCase):
class ContainerTest(FindInit, TestCase):
fixtures = WAREHOUSE_FIXTURES
- def testFormCreation(self):
+ def test_form_creation(self):
main_warehouse = models.Warehouse.objects.create(
name="Main",
warehouse_type=models.WarehouseType.objects.all()[0]
@@ -208,7 +207,7 @@ class ContainerTest(FindInit, TestCase):
self.assertEqual(models.Container.objects.count(),
self.container_number + 1)
- def testChangeLocation(self):
+ def test_change_location(self):
main_warehouse = models.Warehouse.objects.create(
name="Main",
warehouse_type=models.WarehouseType.objects.all()[0]
@@ -222,13 +221,17 @@ class ContainerTest(FindInit, TestCase):
location=main_warehouse,
container_type=models.ContainerType.objects.all()[0]
)
+ container.save()
+ container = models.Container.objects.get(pk=container.pk)
+ self.assertIn(main_warehouse.name, container.cached_location)
+
models.ContainerLocalisation.objects.create(
container=container, division=div_link,
)
self.assertTrue(models.ContainerLocalisation.objects.filter(
division__warehouse=main_warehouse).count())
- # changing location remove unrelevent localisation
+ # changing location remove irrelevant localisation
other_warehouse = models.Warehouse.objects.create(
name="Other",
warehouse_type=models.WarehouseType.objects.all()[0]
@@ -238,3 +241,75 @@ class ContainerTest(FindInit, TestCase):
self.assertFalse(models.ContainerLocalisation.objects.filter(
division__warehouse=main_warehouse).count())
+ def test_update_containers_on_warehouse_update(self):
+ main_warehouse = models.Warehouse.objects.create(
+ name="Main",
+ warehouse_type=models.WarehouseType.objects.all()[0]
+ )
+ container = models.Container.objects.create(
+ reference="Test", responsible=main_warehouse,
+ location=main_warehouse,
+ container_type=models.ContainerType.objects.all()[0]
+ )
+ container.save()
+ container = models.Container.objects.get(pk=container.pk)
+ self.assertIn(main_warehouse.name, container.cached_location)
+ main_warehouse.name = "New name"
+ main_warehouse.save()
+ self.assertEqual(
+ models.Container.objects.filter(
+ need_update=True
+ ).count(), 1)
+ self.assertEqual(
+ models.Container.objects.filter(
+ pk=container.pk,
+ need_update=True
+ ).count(), 1)
+ container = models.Container.objects.get(pk=container.pk)
+ # process pending update
+ container.skip_history_when_saving = True
+ container._no_move = True
+ container.save()
+ container = models.Container.objects.get(pk=container.pk)
+ self.assertIn("New name", container.cached_location)
+
+ def test_update_container_localisation_on_warehouse_update(self):
+ profile, created = IshtarSiteProfile.objects.get_or_create(
+ slug='default', active=True)
+ profile.mapping = True
+ profile.locate_warehouses = True
+ profile.save()
+ wgs84 = SpatialReferenceSystem.objects.get(srid=4326)
+ main_warehouse = models.Warehouse.objects.create(
+ name="Main",
+ warehouse_type=models.WarehouseType.objects.all()[0],
+ )
+ container = models.Container.objects.create(
+ reference="Test", responsible=main_warehouse,
+ location=main_warehouse,
+ container_type=models.ContainerType.objects.all()[0]
+ )
+ container.save()
+ self.assertEqual(container.x, None)
+
+ main_warehouse = models.Warehouse.objects.get(pk=main_warehouse.pk)
+ main_warehouse.x, main_warehouse.y = 33, 42
+ main_warehouse.spatial_reference_system = wgs84
+ main_warehouse.save()
+ # an update is pending
+ self.assertEqual(
+ models.Container.objects.filter(
+ pk=container.pk,
+ need_update=True
+ ).count(), 1)
+
+ # process pending update
+ container = models.Container.objects.get(pk=container.pk)
+ self.assertEqual(container.x, None) # update has to be done
+ container.skip_history_when_saving = True
+ container._no_move = True
+ container.save()
+
+ container = models.Container.objects.get(pk=container.pk)
+ self.assertEqual(container.x, 33)
+
diff --git a/conf/ishtar-pending-update-cron b/conf/ishtar-pending-update-cron
new file mode 100755
index 000000000..269d41859
--- /dev/null
+++ b/conf/ishtar-pending-update-cron
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+ISHTAR_PATH="/srv/ishtar"
+APPS="my_app my_second_app"
+
+for APP in $APPS; do
+ cd $ISHTAR_PATH/$APP
+ python3 manage.py process_pending_update --quiet
+done
+
diff --git a/ishtar_common/management/commands/process_pending_update.py b/ishtar_common/management/commands/process_pending_update.py
new file mode 100644
index 000000000..f0e908d42
--- /dev/null
+++ b/ishtar_common/management/commands/process_pending_update.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright (C) 2013-2018 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# See the file COPYING for details.
+
+import sys
+
+from django.core.management.base import BaseCommand
+
+from django.apps import apps
+
+
+APPS = ['ishtar_common', 'archaeological_operations',
+ 'archaeological_context_records', 'archaeological_finds',
+ 'archaeological_warehouse']
+
+
+class Command(BaseCommand):
+ args = ''
+ help = 'Process pending update of cached labels and geo position'
+
+ def add_arguments(self, parser):
+ parser.add_argument(
+ '--quiet', dest='quiet', action='store_true',
+ help='Quiet output')
+
+ def handle(self, *args, **options):
+ quiet = options['quiet']
+ for app in APPS:
+ if not quiet:
+ print(u"* app: {}".format(app))
+ for model in apps.get_app_config(app).get_models():
+ if model.__name__.startswith('Historical'):
+ continue
+ if not bool(
+ [True for k in model._meta.get_fields()
+ if k == "need_update"]):
+ continue
+ msg = u"-> processing {}: ".format(model._meta.verbose_name)
+ ln = model.objects.count()
+ for idx, obj_id in enumerate(
+ model.objects.filter(
+ need_update=True).values('pk').all()):
+ obj = model.objects.get(pk=obj_id['pk'])
+ obj.skip_history_when_saving = True
+ obj._no_move = True
+ cmsg = u"\r{} {}/{}".format(msg, idx + 1, ln)
+ if not quiet:
+ sys.stdout.write(cmsg)
+ sys.stdout.flush()
+ obj.save()
+ if not quiet:
+ sys.stdout.write("\n")
diff --git a/ishtar_common/migrations/0097_auto_20190628_1256.py b/ishtar_common/migrations/0097_auto_20190628_1256.py
new file mode 100644
index 000000000..f8713d64d
--- /dev/null
+++ b/ishtar_common/migrations/0097_auto_20190628_1256.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.18 on 2019-06-28 12:56
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('ishtar_common', '0096_tinyurl'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='document',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='historicalorganization',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='historicalperson',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='organization',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ migrations.AddField(
+ model_name='person',
+ name='need_update',
+ field=models.BooleanField(default=False, verbose_name='Need update'),
+ ),
+ ]
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index a03f9f387..93a099b74 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -87,7 +87,7 @@ from ishtar_common.models_imports import ImporterModel, ImporterType, \
Import, TargetKeyGroup, ValueFormater
from ishtar_common.templatetags.link_to_window import simple_link_to_window
from ishtar_common.utils import get_cache, disable_for_loaddata, create_slug, \
- get_all_field_names, merge_tsvectors, cached_label_changed, \
+ get_all_field_names, merge_tsvectors, cached_label_changed, post_save_geo, \
generate_relation_graph, max_size_help, task, SecretaryRenderer
__all__ = [
@@ -1963,6 +1963,7 @@ class BaseHistorizedItem(StatisticItem, TemplateItem, FullSearch, Imported,
SHOW_URL = None
EXTERNAL_ID_KEY = ''
EXTERNAL_ID_DEPENDENCIES = []
+ DOWN_MODEL_UPDATE = []
HISTORICAL_M2M = []
history_modifier = models.ForeignKey(
@@ -1973,6 +1974,8 @@ class BaseHistorizedItem(StatisticItem, TemplateItem, FullSearch, Imported,
verbose_name=_("Creator"), blank=True, null=True)
last_modified = models.DateTimeField(auto_now=True)
history_m2m = JSONField(default={}, blank=True)
+ need_update = models.BooleanField(
+ verbose_name=_("Need update"), default=False)
ALT_NAMES = {
'history_creator': SearchAltName(
@@ -1992,6 +1995,15 @@ class BaseHistorizedItem(StatisticItem, TemplateItem, FullSearch, Imported,
class Meta:
abstract = True
+ def cascade_update(self):
+ for down_model in self.DOWN_MODEL_UPDATE:
+ if not settings.USE_BACKGROUND_TASK:
+ getattr(self, down_model).update(need_update=True)
+ continue
+ for item in getattr(self, down_model).all():
+ cached_label_changed(item.model, instance=item)
+ post_save_geo(item.model, instance=item)
+
@classmethod
def get_verbose_name(cls):
return cls._meta.verbose_name
diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py
index a2fdd36f3..f3df5c282 100644
--- a/ishtar_common/utils.py
+++ b/ishtar_common/utils.py
@@ -419,6 +419,11 @@ EXTRA_KWARGS_TRIGGER = [
]
+def cached_label_and_geo_changed(sender, **kwargs):
+ cached_label_changed(sender=sender, **kwargs)
+ post_save_geo(sender=sender, **kwargs)
+
+
def cached_label_changed(sender, **kwargs):
if not kwargs.get('instance'):
return
@@ -454,11 +459,13 @@ def _cached_label_changed(sender, **kwargs):
return
force_update = kwargs.get('force_update', False)
+ if hasattr(instance, "need_update") and instance.need_update:
+ force_update = True
+ instance.skip_history_when_saving = True
+
if not force_update and getattr(instance, '_cached_label_checked', False):
return
- force_update = kwargs.get('force_update', False)
-
if hasattr(instance, "refresh_cache"):
instance.refresh_cache()
@@ -475,12 +482,19 @@ def _cached_label_changed(sender, **kwargs):
if lbl != getattr(instance, cached_label):
changed.append((cached_label, lbl))
setattr(instance, cached_label, lbl) # update for cache
+
+ if hasattr(instance, "need_update") and instance.need_update:
+ changed.append(("need_update", False))
+ instance.need_update = False
+
if changed:
instance._search_updated = False
if hasattr(instance, '_cascade_change') and instance._cascade_change:
instance.skip_history_when_saving = True
instance.__class__.objects.filter(pk=instance.pk).update(
**dict(changed))
+ if (changed or not cached_labels) and hasattr(instance, "cascade_update"):
+ instance.cascade_update()
updated = False
if force_update or hasattr(instance, 'update_search_vector'):
updated = instance.update_search_vector()
@@ -837,11 +851,17 @@ def _post_save_geo(sender, **kwargs):
instance.point_source = None
modified = True
+ if hasattr(instance, "need_update") and instance.need_update:
+ instance.need_update = False
+ modified = True
+
if modified:
instance.skip_history_when_saving = True
instance._post_saved_geo = True
instance._cached_label_checked = False
instance.save()
+ if hasattr(instance, "cascade_update"):
+ instance.cascade_update()
cache_key, __ = get_cache(
sender, ["post_save_geo", instance.pk]
)