diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2019-06-28 14:50:12 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2019-06-28 14:50:12 +0200 |
commit | 3eee5bac1748181d41d7abc32da1570a1fce6645 (patch) | |
tree | 2f2f39dfb5c185d8e8857b2f87bbeff6065bb321 | |
parent | f1366d27a7ccfcd2745aa0854f217941f6b2198c (diff) | |
download | Ishtar-3eee5bac1748181d41d7abc32da1570a1fce6645.tar.bz2 Ishtar-3eee5bac1748181d41d7abc32da1570a1fce6645.zip |
Better management of cascade updates
-rw-r--r-- | archaeological_context_records/migrations/0047_auto_20190628_1257.py | 25 | ||||
-rw-r--r-- | archaeological_context_records/models.py | 1 | ||||
-rw-r--r-- | archaeological_files/migrations/0019_auto_20190628_1257.py | 25 | ||||
-rw-r--r-- | archaeological_finds/migrations/0067_auto_20190628_1257.py | 60 | ||||
-rw-r--r-- | archaeological_finds/tests.py | 46 | ||||
-rw-r--r-- | archaeological_operations/migrations/0056_auto_20190628_1257.py | 55 | ||||
-rw-r--r-- | archaeological_operations/models.py | 3 | ||||
-rw-r--r-- | archaeological_warehouse/migrations/0037_auto_20190628_1257.py | 36 | ||||
-rw-r--r-- | archaeological_warehouse/models.py | 32 | ||||
-rw-r--r-- | archaeological_warehouse/tests.py | 85 | ||||
-rwxr-xr-x | conf/ishtar-pending-update-cron | 10 | ||||
-rw-r--r-- | ishtar_common/management/commands/process_pending_update.py | 67 | ||||
-rw-r--r-- | ishtar_common/migrations/0097_auto_20190628_1256.py | 40 | ||||
-rw-r--r-- | ishtar_common/models.py | 14 | ||||
-rw-r--r-- | ishtar_common/utils.py | 24 |
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] ) |