Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(apis_entities, generic): move merge logic to GenericModel #1478

Merged
merged 2 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 0 additions & 43 deletions apis_core/apis_entities/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion apis_core/apis_relations/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

from django.dispatch import receiver

from apis_core.apis_entities.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
from apis_core.generic.signals import post_merge_with

logger = logging.getLogger(__name__)

Expand Down
42 changes: 42 additions & 0 deletions apis_core/generic/abc.py
Original file line number Diff line number Diff line change
@@ -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.signals import post_merge_with, pre_merge_with


class GenericModel:
Expand Down Expand Up @@ -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()
File renamed without changes.
2 changes: 1 addition & 1 deletion apis_core/relations/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
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.apis_metainfo.signals import post_duplicate
from apis_core.generic.signals import post_merge_with
from apis_core.relations.models import Relation

logger = logging.getLogger(__name__)
Expand Down
Loading