summaryrefslogtreecommitdiff
path: root/ishtar_common/models_common.py
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2022-10-06 16:00:40 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2022-12-12 12:23:18 +0100
commit43010940511b29eeba2be1f985d3b97b1ac7e62d (patch)
tree488d49c8ec2cd6443a42fb70c0073ab56883d3d5 /ishtar_common/models_common.py
parent4b22b3a77938aaec4c21c921c90e922fe526c43c (diff)
downloadIshtar-43010940511b29eeba2be1f985d3b97b1ac7e62d.tar.bz2
Ishtar-43010940511b29eeba2be1f985d3b97b1ac7e62d.zip
Geodata: manage cascade remove and geodata clear
Diffstat (limited to 'ishtar_common/models_common.py')
-rw-r--r--ishtar_common/models_common.py73
1 files changed, 64 insertions, 9 deletions
diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py
index d32f835bd..adf1c1516 100644
--- a/ishtar_common/models_common.py
+++ b/ishtar_common/models_common.py
@@ -2581,18 +2581,13 @@ class GeoVectorData(Imported, OwnPerms):
post_save.connect(post_save_geodata, sender=GeoVectorData)
-def geodata_attached_changed(sender, **kwargs):
- # manage main geoitem and cascade association
- instance = kwargs.get("instance", None)
- model = kwargs.get("model", None)
- pk_set = kwargs.get("pk_set", None)
- if not instance or not model or not pk_set:
- return
+def geodata_attached_post_add(model, instance, pk_set):
item_pks = list(model.objects.filter(pk__in=pk_set).values_list("pk", flat=True))
if not item_pks:
return
- if not hasattr(instance, "_geodata"): # use a cache to manage during geodata attach
+ # use a cache to manage during geodata attach
+ if not hasattr(instance, "_geodata"):
instance._geodata = []
if not instance.main_geodata_id:
instance.main_geodata_id = item_pks[0]
@@ -2617,11 +2612,71 @@ def geodata_attached_changed(sender, **kwargs):
if not q.count():
if not child:
child = model.objects.get(pk=pk)
- if not pk in geoitems:
+ if pk not in geoitems:
geoitems[pk] = GeoVectorData.objects.get(pk=pk)
child_model.objects.get(pk=child_id).geodata.add(geoitems[pk])
+def geodata_attached_remove(model, instance, pk_set=None, clear=False):
+ if clear:
+ item_pks = getattr(instance, "_geodata_clear_item_pks", [])
+ else:
+ item_pks = list(model.objects.filter(pk__in=pk_set).values_list("pk", flat=True))
+ if not item_pks:
+ return
+
+ # use a cache to manage during geodata attach
+ if not hasattr(instance, "_geodata"):
+ instance._geodata = []
+ if instance.main_geodata_id in item_pks:
+ instance.main_geodata_id = None
+ instance.skip_history_when_saving = True
+ instance._no_move = True
+ if not hasattr(instance, "_geodata"):
+ instance._geodata = []
+ instance._geodata += [pk for pk in item_pks if pk not in instance._geodata]
+ instance.save()
+
+ # for all sub item verify that the geo items are present
+ for query in instance.geodata_child_item_queries():
+ child_model = query.model
+ m2m_model = child_model.geodata.through
+ m2m_key = f"{child_model._meta.model_name}_id"
+ geoitems = {}
+ for child_id in query.values_list("id", flat=True):
+ child = None
+ for pk in item_pks:
+ q = m2m_model.objects.filter(**{m2m_key: child_id,
+ "geovectordata_id": pk})
+ if q.count():
+ if not child:
+ child = model.objects.get(pk=pk)
+ if pk not in geoitems:
+ geoitems[pk] = GeoVectorData.objects.get(pk=pk)
+ child_model.objects.get(pk=child_id).geodata.remove(geoitems[pk])
+
+
+def geodata_attached_changed(sender, **kwargs):
+ # manage main geoitem and cascade association
+ instance = kwargs.get("instance", None)
+ model = kwargs.get("model", None)
+ pk_set = kwargs.get("pk_set", None)
+ action = kwargs.get("action", None)
+ if not instance or not model:
+ return
+
+ if action == "post_add":
+ geodata_attached_post_add(model, instance, pk_set)
+ elif action == "post_remove":
+ geodata_attached_remove(model, instance, pk_set)
+ elif action == "pre_clear":
+ instance._geodata_clear_item_pks = list(
+ instance.geodata.values_list("id", flat=True)
+ )
+ elif action == "post_clear":
+ geodata_attached_remove(model, instance, clear=True)
+
+
class GeographicItem(models.Model):
main_geodata = models.ForeignKey(
GeoVectorData,