Coverage for clustersoftware/models.py: 92%

40 statements  

« prev     ^ index     » next       coverage.py v7.17.0, created at 2026-10-24 19:06 +0000

1from django.db import models 

2from django.db.models import Q 

3from django.urls import reverse 

4from simple_history.models import HistoricalRecords 

5from vendor.models import Model as VendorModel 

6from django.contrib.auth.models import Group 

7from taggit.managers import TaggableManager 

8 

9from . import app_label 

10 

11 

12class ClusterSoftwareManager(models.Manager): 

13 def get_by_natural_key(self, vendor, name, version): 

14 if isinstance(vendor, (list, tuple)): 

15 vendor = vendor[0] 

16 return self.get(vendor__name=vendor, name=name, version=version) 

17 

18 

19class Model(models.Model): 

20 objects = ClusterSoftwareManager() 

21 history = HistoricalRecords() 

22 name = models.CharField(max_length=45) 

23 version = models.CharField(max_length=45, default="", blank=True) 

24 vendor = models.ForeignKey( 

25 VendorModel, 

26 related_name="%s_set" % app_label, 

27 related_query_name="%s" % app_label, 

28 on_delete=models.PROTECT, 

29 ) 

30 

31 group = models.ForeignKey( 

32 Group, 

33 editable=False, 

34 blank=True, 

35 null=True, 

36 on_delete=models.PROTECT, 

37 related_name="clustersoftwares", 

38 ) 

39 

40 tags = TaggableManager(blank=True, related_name="clustersoftware_tags") 

41 

42 def __str__(self): 

43 if self.name and self.version: 

44 return "{} {}".format(self.name, self.version) 

45 if self.name and not self.version: 

46 return "%s" % (self.name) 

47 return self # pragma: no cover 

48 

49 def natural_key(self): 

50 return self.vendor.natural_key() + (self.name, self.version) 

51 

52 natural_key.dependencies = ["vendor.Model"] 

53 

54 @classmethod 

55 def get_natural_key_fields(cls): 

56 return ["vendor__name", "name", "version"] 

57 

58 @classmethod 

59 def get_natural_key_info(cls): 

60 return [("vendor", VendorModel), ("name", None), ("version", None)] 

61 

62 def get_absolute_url(self): 

63 

64 return reverse("%s:detail" % app_label, kwargs={"pk": self.pk}) 

65 

66 class Meta: 

67 db_table = "{}_{}".format("sm", app_label) 

68 constraints = [ 

69 models.UniqueConstraint( 

70 fields=["vendor", "name", "version", "group"], 

71 name="unique_sm_clustersoftware_vendor_name_version_group", 

72 ), 

73 # PostgreSQL treats NULLs as distinct, so the constraint above 

74 # cannot deduplicate global (group=NULL) rows. Keep reference data 

75 # globally unique with a partial constraint. 

76 models.UniqueConstraint( 

77 fields=["vendor", "name", "version"], 

78 condition=Q(group__isnull=True), 

79 name="unique_sm_clustersoftware_global_vendor_name_version", 

80 ), 

81 ]