Coverage for apis_core/apis_entities/models.py: 59%
61 statements
« prev ^ index » next coverage.py v7.6.8, created at 2024-12-20 09:24 +0000
« prev ^ index » next coverage.py v7.6.8, created at 2024-12-20 09:24 +0000
1import functools
2import re
4from django.conf import settings
5from django.db.models.signals import post_save
6from django.dispatch import receiver
7from django.urls import NoReverseMatch, reverse
9from apis_core.apis_metainfo.models import RootObject, Uri
11NEXT_PREV = getattr(settings, "APIS_NEXT_PREV", True)
14class AbstractEntity(RootObject):
15 """
16 Abstract super class which encapsulates common logic between the
17 different entity kinds and provides various methods relating to either
18 all or one specific entity kind.
20 Most of the class methods are designed to be used in the subclass as they
21 are considering contexts which depend on the subclass entity type.
22 So they are to be understood in that dynamic context.
23 """
25 class Meta:
26 abstract = True
28 @classmethod
29 def get_or_create_uri(cls, uri):
30 uri = str(uri)
31 try:
32 if re.match(r"^[0-9]*$", uri):
33 p = cls.objects.get(pk=uri)
34 else:
35 p = cls.objects.get(uri__uri=uri)
36 return p
37 except Exception as e:
38 print("Found no object corresponding to given uri." + e)
39 return False
41 # TODO
42 @classmethod
43 def get_entity_list_filter(cls):
44 return None
46 @functools.cached_property
47 def get_prev_id(self):
48 if NEXT_PREV:
49 prev_instance = (
50 type(self)
51 .objects.filter(id__lt=self.id)
52 .order_by("-id")
53 .only("id")
54 .first()
55 )
56 if prev_instance is not None:
57 return prev_instance.id
58 return False
60 @functools.cached_property
61 def get_next_id(self):
62 if NEXT_PREV:
63 next_instance = (
64 type(self)
65 .objects.filter(id__gt=self.id)
66 .order_by("id")
67 .only("id")
68 .first()
69 )
70 if next_instance is not None:
71 return next_instance.id
72 return False
74 def get_duplicate_url(self):
75 entity = self.__class__.__name__.lower()
76 return reverse(
77 "apis_core:apis_entities:generic_entities_duplicate_view",
78 kwargs={"contenttype": entity, "pk": self.id},
79 )
81 def merge_start_date_written(self, other):
82 self.start_date_written = self.start_date_written or other.start_date_written
84 def merge_end_date_written(self, other):
85 self.end_date_written = self.end_date_written or other.end_date_written
88@receiver(post_save, dispatch_uid="create_default_uri")
89def create_default_uri(sender, instance, created, raw, using, update_fields, **kwargs):
90 # disable the handler during fixture loading
91 if raw:
92 return
93 create_default_uri = getattr(settings, "CREATE_DEFAULT_URI", True)
94 skip_default_uri = getattr(instance, "skip_default_uri", False)
95 if create_default_uri and not skip_default_uri:
96 if isinstance(instance, AbstractEntity) and created:
97 base = getattr(settings, "APIS_BASE_URI", "https://example.org").strip("/")
98 try:
99 route = reverse("GetEntityGenericRoot", kwargs={"pk": instance.pk})
100 except NoReverseMatch:
101 route = reverse(
102 "apis_core:GetEntityGeneric", kwargs={"pk": instance.pk}
103 )
104 uri = f"{base}{route}"
105 Uri.objects.create(uri=uri, root_object=instance)