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

1import functools 

2import re 

3 

4from django.conf import settings 

5from django.db.models.signals import post_save 

6from django.dispatch import receiver 

7from django.urls import NoReverseMatch, reverse 

8 

9from apis_core.apis_metainfo.models import RootObject, Uri 

10 

11NEXT_PREV = getattr(settings, "APIS_NEXT_PREV", True) 

12 

13 

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. 

19 

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 """ 

24 

25 class Meta: 

26 abstract = True 

27 

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 

40 

41 # TODO 

42 @classmethod 

43 def get_entity_list_filter(cls): 

44 return None 

45 

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 

59 

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 

73 

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 ) 

80 

81 def merge_start_date_written(self, other): 

82 self.start_date_written = self.start_date_written or other.start_date_written 

83 

84 def merge_end_date_written(self, other): 

85 self.end_date_written = self.end_date_written or other.end_date_written 

86 

87 

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)