Coverage for vocabs/models.py: 64%

170 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2024-07-27 11:19 +0000

1from django.db import models 

2from django.conf import settings 

3from django.urls import reverse 

4 

5from django.utils.text import slugify 

6from django.utils.functional import cached_property 

7 

8 

9try: 

10 DEFAULT_NAMESPACE = settings.VOCABS_SETTINGS["default_nsgg"] 

11except KeyError: 

12 DEFAULT_NAMESPACE = "http://www.vocabs/provide-some-namespace/" 

13 

14try: 

15 DEFAULT_PREFIX = settings.VOCABS_SETTINGS["default_prefix"] 

16except KeyError: 

17 DEFAULT_PREFIX = "provideSome" 

18 

19try: 

20 DEFAULT_LANG = settings.VOCABS_SETTINGS["default_lang"] 

21except KeyError: 

22 DEFAULT_LANG = "eng" 

23 

24 

25LABEL_TYPES = ( 

26 ("prefLabel", "prefLabel"), 

27 ("altLabel", "altLabel"), 

28 ("hiddenLabel", "hiddenLabel"), 

29) 

30 

31 

32class SkosNamespace(models.Model): 

33 namespace = models.URLField(blank=True, default=DEFAULT_NAMESPACE) 

34 prefix = models.CharField(max_length=50, blank=True, default=DEFAULT_PREFIX) 

35 

36 def __str__(self): 

37 return "{}".format(self.prefix) 

38 

39 class Meta: 

40 ordering = ["id"] 

41 

42 

43class SkosConceptScheme(models.Model): 

44 dc_title = models.CharField(max_length=300, blank=True) 

45 namespace = models.ForeignKey( 

46 SkosNamespace, blank=True, null=True, on_delete=models.SET_NULL 

47 ) 

48 dct_creator = models.URLField(blank=True) 

49 legacy_id = models.CharField(max_length=200, blank=True) 

50 

51 def save(self, *args, **kwargs): 

52 if self.namespace is None: 

53 temp_namespace, _ = SkosNamespace.objects.get_or_create( 

54 namespace=DEFAULT_NAMESPACE, prefix=DEFAULT_PREFIX 

55 ) 

56 temp_namespace.save() 

57 self.namespace = temp_namespace 

58 else: 

59 pass 

60 super(SkosConceptScheme, self).save(*args, **kwargs) 

61 

62 @classmethod 

63 def get_listview_url(self): 

64 return reverse("vocabs:browse_schemes") 

65 

66 @classmethod 

67 def get_createview_url(self): 

68 return reverse("vocabs:skosconceptscheme_create") 

69 

70 def get_absolute_url(self): 

71 return reverse("vocabs:skosconceptscheme_detail", kwargs={"pk": self.id}) 

72 

73 def get_next(self): 

74 next = SkosConceptScheme.objects.filter(id__gt=self.id) 

75 if next: 

76 return next.first().id 

77 return False 

78 

79 def get_prev(self): 

80 prev = SkosConceptScheme.objects.filter(id__lt=self.id).order_by("-id") 

81 if prev: 

82 return prev.first().id 

83 return False 

84 

85 def __str__(self): 

86 return "{}:{}".format(self.namespace, self.dc_title) 

87 

88 class Meta: 

89 ordering = ["id"] 

90 

91 

92class SkosLabel(models.Model): 

93 label = models.CharField( 

94 max_length=100, blank=True, help_text="The entities label or name." 

95 ) 

96 label_type = models.CharField( 

97 max_length=30, 

98 blank=True, 

99 choices=LABEL_TYPES, 

100 help_text="The type of the label.", 

101 ) 

102 isoCode = models.CharField( 

103 max_length=3, 

104 blank=True, 

105 help_text="The ISO 639-3 code for the label's language.", 

106 ) 

107 

108 @classmethod 

109 def get_listview_url(self): 

110 return reverse("vocabs:browse_skoslabels") 

111 

112 @classmethod 

113 def get_createview_url(self): 

114 return reverse("vocabs:skoslabel_create") 

115 

116 def get_absolute_url(self): 

117 return reverse("vocabs:skoslabel_detail", kwargs={"pk": self.id}) 

118 

119 def get_next(self): 

120 next = SkosLabel.objects.filter(id__gt=self.id) 

121 if next: 

122 return next.first().id 

123 return False 

124 

125 def get_prev(self): 

126 prev = SkosLabel.objects.filter(id__lt=self.id).order_by("-id") 

127 if prev: 

128 return prev.first().id 

129 return False 

130 

131 def __str__(self): 

132 if self.label_type != "": 

133 return "{} @{} ({})".format(self.label, self.isoCode, self.label_type) 

134 else: 

135 return "{} @{}".format(self.label, self.isoCode) 

136 

137 class Meta: 

138 ordering = ["id"] 

139 

140 

141class SkosConcept(models.Model): 

142 pref_label = models.CharField(max_length=300, blank=True) 

143 pref_label_lang = models.CharField(max_length=3, blank=True, default=DEFAULT_LANG) 

144 scheme = models.ManyToManyField( 

145 SkosConceptScheme, blank=True, related_name="has_concepts" 

146 ) 

147 definition = models.TextField(blank=True) 

148 definition_lang = models.CharField(max_length=3, blank=True, default=DEFAULT_LANG) 

149 notation = models.CharField(max_length=300, blank=True) 

150 namespace = models.ForeignKey( 

151 SkosNamespace, blank=True, null=True, on_delete=models.SET_NULL 

152 ) 

153 broader_concept = models.ForeignKey( 

154 "SkosConcept", 

155 help_text="Broader Term.", 

156 verbose_name="Broader Term", 

157 blank=True, 

158 null=True, 

159 on_delete=models.SET_NULL, 

160 related_name="narrower_concepts", 

161 ) 

162 skos_broader = models.ManyToManyField( 

163 "SkosConcept", blank=True, related_name="narrower" 

164 ) 

165 skos_narrower = models.ManyToManyField( 

166 "SkosConcept", blank=True, related_name="broader" 

167 ) 

168 skos_related = models.ManyToManyField( 

169 "SkosConcept", blank=True, related_name="related" 

170 ) 

171 skos_broadmatch = models.ManyToManyField( 

172 "SkosConcept", blank=True, related_name="broadmatch" 

173 ) 

174 skos_exactmatch = models.ManyToManyField( 

175 "SkosConcept", blank=True, related_name="exactmatch" 

176 ) 

177 skos_closematch = models.ManyToManyField( 

178 "SkosConcept", blank=True, related_name="closematch" 

179 ) 

180 legacy_id = models.CharField(max_length=200, blank=True) 

181 name_reverse = models.CharField( 

182 max_length=255, 

183 verbose_name="Name reverse", 

184 help_text='Inverse relation like: \ 

185 "is sub-class of" vs. "is super-class of".', 

186 blank=True, 

187 ) 

188 

189 def get_broader(self): 

190 broader = self.skos_broader.all() 

191 broader_reverse = SkosConcept.objects.filter(skos_narrower=self) 

192 all_broader = set(list(broader) + list(broader_reverse)) 

193 return all_broader 

194 

195 def get_narrower(self): 

196 narrower = self.skos_narrower.all() 

197 narrower_reverse = SkosConcept.objects.filter(skos_broader=self) 

198 all_narrower = set(list(narrower) + list(narrower_reverse)) 

199 return all_narrower 

200 

201 @property 

202 def all_schemes(self): 

203 return ", ".join([x.dc_title for x in self.scheme.all()]) 

204 

205 def save(self, *args, **kwargs): 

206 if self.notation == "": 

207 temp_notation = slugify(self.pref_label, allow_unicode=True) 

208 concepts = len(SkosConcept.objects.filter(notation=temp_notation)) 

209 if concepts < 1: 

210 self.notation = temp_notation 

211 else: 

212 self.notation = "{}-{}".format(temp_notation, concepts) 

213 else: 

214 pass 

215 

216 if self.namespace is None: 

217 temp_namespace, _ = SkosNamespace.objects.get_or_create( 

218 namespace=DEFAULT_NAMESPACE, prefix=DEFAULT_PREFIX 

219 ) 

220 temp_namespace.save() 

221 self.namespace = temp_namespace 

222 else: 

223 pass 

224 super(SkosConcept, self).save(*args, **kwargs) 

225 

226 @cached_property 

227 def label(self): 

228 # 'borrowed from https://github.com/sennierer' 

229 d = self 

230 res = self.pref_label 

231 while d.broader_concept: 

232 res = d.broader_concept.pref_label + " >> " + res 

233 d = d.broader_concept 

234 return res 

235 

236 @classmethod 

237 def get_listview_url(self): 

238 return reverse("vocabs:browse_vocabs") 

239 

240 @classmethod 

241 def get_createview_url(self): 

242 return reverse("vocabs:skosconcept_create") 

243 

244 def get_absolute_url(self): 

245 return reverse("vocabs:skosconcept_detail", kwargs={"pk": self.id}) 

246 

247 def get_next(self): 

248 next = SkosConcept.objects.filter(id__gt=self.id) 

249 if next: 

250 return next.first().id 

251 return False 

252 

253 def get_prev(self): 

254 prev = SkosConcept.objects.filter(id__lt=self.id).order_by("-id") 

255 if prev: 

256 return prev.first().id 

257 return False 

258 

259 def __str__(self): 

260 return self.pref_label 

261 

262 class Meta: 

263 ordering = ["id"] 

264 

265 

266def get_all_children(self, include_self=True): 

267 # many thanks to https://stackoverflow.com/questions/4725343 

268 r = [] 

269 if include_self: 

270 r.append(self) 

271 for c in SkosConcept.objects.filter(broader_concept=self): 

272 _r = get_all_children(c, include_self=True) 

273 if 0 < len(_r): 

274 r.extend(_r) 

275 return r