Coverage for apis_core/collections/models.py: 86%
37 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
1from django.contrib.contenttypes.fields import GenericForeignKey
2from django.contrib.contenttypes.models import ContentType
3from django.db import models
5from apis_core.generic.abc import GenericModel
8class SkosCollectionManager(models.Manager):
9 def get_by_full_path(self, name: str):
10 """
11 Return a collection specified by its full path, from the root colletion
12 to the leaf collection, delimited by `|`. I.e. if there is a collection
13 named `foo` and it has a parent named `bar` and `bar` does not have a
14 parent, then you can use the string "bar|foo" to get the `foo` collection.
15 """
16 names = name.split("|")
17 parent = None
18 while names:
19 parent = self.get(parent=parent, name=names.pop(0))
20 return parent
23class SkosCollection(GenericModel, models.Model):
24 """
25 SKOS collections are labeled and/or ordered groups of SKOS concepts.
26 Collections are useful where a group of concepts shares something in common,
27 and it is convenient to group them under a common label, or
28 where some concepts can be placed in a meaningful order.
30 Miles, Alistair, and Sean Bechhofer. "SKOS simple knowledge
31 organization system reference. W3C recommendation (2009)."
33 """
35 class Meta:
36 ordering = ["name"]
37 constraints = [
38 models.UniqueConstraint(
39 fields=(
40 "name",
41 "parent",
42 ),
43 name="unique_name_parent",
44 nulls_distinct=False,
45 violation_error_message="The combination of name and parent collection must be unique",
46 ),
47 models.CheckConstraint(
48 check=~models.Q(name__contains="|"),
49 name="check_name_pipe",
50 violation_error_message="The name must not contain the pipe symbol: |",
51 ),
52 ]
54 parent = models.ForeignKey("self", null=True, on_delete=models.CASCADE, blank=True)
55 name = models.CharField(
56 max_length=300,
57 verbose_name="skos:prefLabel",
58 help_text="Collection label or name",
59 )
60 label_lang = models.CharField(
61 max_length=3,
62 blank=True,
63 default="en",
64 verbose_name="skos:prefLabel language",
65 help_text="Language of preferred label given above",
66 )
67 creator = models.TextField(
68 blank=True,
69 verbose_name="dc:creator",
70 help_text="Person or organisation that created this collection"
71 "If more than one list all using a semicolon ;",
72 )
73 contributor = models.TextField(
74 blank=True,
75 verbose_name="dc:contributor",
76 help_text="Person or organisation that made contributions to the collection"
77 "If more than one list all using a semicolon ;",
78 )
79 objects = SkosCollectionManager()
81 def __str__(self):
82 return self.name
84 def children(self):
85 return SkosCollection.objects.filter(parent=self)
87 def children_tree_as_list(self):
88 childtrees = [self]
89 for child in self.children():
90 childtrees.extend(child.children_tree_as_list())
91 return childtrees
94class SkosCollectionContentObject(GenericModel, models.Model):
95 """
96 *Throughtable* datamodel to connect collections to arbitrary content
97 """
99 collection = models.ForeignKey(SkosCollection, on_delete=models.CASCADE)
101 content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
102 object_id = models.PositiveIntegerField()
103 content_object = GenericForeignKey("content_type", "object_id")
105 def __str__(self):
106 return f"{self.content_object} -> {self.collection}"