diff --git a/apis_core/apis_entities/models.py b/apis_core/apis_entities/models.py index 2a073032a..275566ef6 100644 --- a/apis_core/apis_entities/models.py +++ b/apis_core/apis_entities/models.py @@ -2,13 +2,10 @@ import re from django.conf import settings -from django.contrib.contenttypes.models import ContentType -from django.db.models.query import QuerySet from django.db.models.signals import post_save from django.dispatch import receiver from django.urls import NoReverseMatch, reverse -from apis_core.apis_entities import signals from apis_core.apis_metainfo.models import RootObject, Uri NEXT_PREV = getattr(settings, "APIS_NEXT_PREV", True) @@ -90,46 +87,6 @@ def merge_start_date_written(self, other): def merge_end_date_written(self, other): self.end_date_written = self.end_date_written or other.end_date_written - def merge_with(self, entities): - if self in entities: - entities.remove(self) - origin = self.__class__ - signals.pre_merge_with.send(sender=origin, instance=self, entities=entities) - - # TODO: check if these imports can be put to top of module without - # causing circular import issues. - from apis_core.apis_metainfo.models import Uri - - e_a = type(self).__name__ - self_model_class = ContentType.objects.get(model__iexact=e_a).model_class() - if isinstance(entities, int): - entities = self_model_class.objects.get(pk=entities) - if not isinstance(entities, list) and not isinstance(entities, QuerySet): - entities = [entities] - entities = [ - self_model_class.objects.get(pk=ent) if isinstance(ent, int) else ent - for ent in entities - ] - for ent in entities: - e_b = type(ent).__name__ - if e_a != e_b: - continue - for f in ent._meta.local_many_to_many: - if not f.name.endswith("_set"): - sl = list(getattr(self, f.name).all()) - for s in getattr(ent, f.name).all(): - if s not in sl: - getattr(self, f.name).add(s) - Uri.objects.filter(root_object=ent).update(root_object=self) - - for ent in entities: - self.merge_fields(ent) - - signals.post_merge_with.send(sender=origin, instance=self, entities=entities) - - for ent in entities: - ent.delete() - def get_serialization(self): from apis_core.apis_entities.serializers_generic import EntitySerializer diff --git a/apis_core/apis_relations/signals.py b/apis_core/apis_relations/signals.py index 4558e7527..f19d1bc96 100644 --- a/apis_core/apis_relations/signals.py +++ b/apis_core/apis_relations/signals.py @@ -2,7 +2,7 @@ from django.dispatch import receiver -from apis_core.apis_entities.signals import post_merge_with +from apis_core.generic.signals import post_merge_with from apis_core.apis_metainfo.models import RootObject from apis_core.apis_metainfo.signals import post_duplicate from apis_core.apis_relations.models import TempTriple diff --git a/apis_core/generic/abc.py b/apis_core/generic/abc.py index d49521bce..58f488f4d 100644 --- a/apis_core/generic/abc.py +++ b/apis_core/generic/abc.py @@ -1,8 +1,10 @@ from django.contrib.contenttypes.models import ContentType from django.db.models import BooleanField, CharField, TextField +from django.db.models.query import QuerySet from django.urls import reverse from apis_core.generic.helpers import permission_fullname +from apis_core.generic.signal import pre_merge_with, post_merge_with class GenericModel: @@ -121,3 +123,43 @@ def merge_fields(self, other): if newval != getattr(self, field.name): setattr(self, field.name, newval) self.save() + + def merge_with(self, entities): + if self in entities: + entities.remove(self) + origin = self.__class__ + pre_merge_with.send(sender=origin, instance=self, entities=entities) + + # TODO: check if these imports can be put to top of module without + # causing circular import issues. + from apis_core.apis_metainfo.models import Uri + + e_a = type(self).__name__ + self_model_class = ContentType.objects.get(model__iexact=e_a).model_class() + if isinstance(entities, int): + entities = self_model_class.objects.get(pk=entities) + if not isinstance(entities, list) and not isinstance(entities, QuerySet): + entities = [entities] + entities = [ + self_model_class.objects.get(pk=ent) if isinstance(ent, int) else ent + for ent in entities + ] + for ent in entities: + e_b = type(ent).__name__ + if e_a != e_b: + continue + for f in ent._meta.local_many_to_many: + if not f.name.endswith("_set"): + sl = list(getattr(self, f.name).all()) + for s in getattr(ent, f.name).all(): + if s not in sl: + getattr(self, f.name).add(s) + Uri.objects.filter(root_object=ent).update(root_object=self) + + for ent in entities: + self.merge_fields(ent) + + post_merge_with.send(sender=origin, instance=self, entities=entities) + + for ent in entities: + ent.delete() diff --git a/apis_core/apis_entities/signals.py b/apis_core/generic/signals.py similarity index 100% rename from apis_core/apis_entities/signals.py rename to apis_core/generic/signals.py diff --git a/apis_core/relations/signals.py b/apis_core/relations/signals.py index 0dfa73e34..cf37983dd 100644 --- a/apis_core/relations/signals.py +++ b/apis_core/relations/signals.py @@ -3,7 +3,7 @@ from django.contrib.contenttypes.models import ContentType from django.dispatch import receiver -from apis_core.apis_entities.signals import post_merge_with +from apis_core.generic.signals import post_merge_with from apis_core.apis_metainfo.signals import post_duplicate from apis_core.relations.models import Relation