diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..de288e1 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.formatting.provider": "black" +} \ No newline at end of file diff --git a/vocabs/models.py b/vocabs/models.py index 8dd336d..08fd738 100644 --- a/vocabs/models.py +++ b/vocabs/models.py @@ -12,53 +12,53 @@ try: - notation_for_uri = settings.VOCABS_SETTINGS['notation_for_uri'] + notation_for_uri = settings.VOCABS_SETTINGS["notation_for_uri"] except KeyError: notation_for_uri = False -VOCABS_SEPARATOR = getattr(settings, 'VOCABS_SEPARATOR', '/') +VOCABS_SEPARATOR = getattr(settings, "VOCABS_SEPARATOR", "/") DEFAULT_URI = "https://vocabs.acdh.oeaw.ac.at/" try: - DEFAULT_NAMESPACE = settings.VOCABS_SETTINGS['default_nsgg'] + DEFAULT_NAMESPACE = settings.VOCABS_SETTINGS["default_nsgg"] except KeyError: DEFAULT_NAMESPACE = "https://vocabs.acdh.oeaw.ac.at/provide-some-namespace" try: - DEFAULT_PREFIX = settings.VOCABS_SETTINGS['default_prefix'] + DEFAULT_PREFIX = settings.VOCABS_SETTINGS["default_prefix"] except KeyError: DEFAULT_PREFIX = "provideSome" try: - DEFAULT_LANG = settings.VOCABS_SETTINGS['default_lang'] + DEFAULT_LANG = settings.VOCABS_SETTINGS["default_lang"] except KeyError: DEFAULT_LANG = "en" LABEL_TYPES = ( - ('prefLabel', 'prefLabel'), - ('altLabel', 'altLabel'), - ('hiddenLabel', 'hiddenLabel'), + ("prefLabel", "prefLabel"), + ("altLabel", "altLabel"), + ("hiddenLabel", "hiddenLabel"), ) NOTE_TYPES = ( - ('note', 'note'), - ('scopeNote', 'scopeNote'), - ('changeNote', 'changeNote'), - ('editorialNote', 'editorialNote'), - ('historyNote', 'historyNote'), - ('definition', 'definition'), - ('example', 'example'), + ("note", "note"), + ("scopeNote", "scopeNote"), + ("changeNote", "changeNote"), + ("editorialNote", "editorialNote"), + ("historyNote", "historyNote"), + ("definition", "definition"), + ("example", "example"), ) SKOS_RELATION_TYPES = [ - ('related', 'related'), - ('broadMatch', 'broad_match'), - ('narrowMatch', 'narrow_match'), - ('exactMatch', 'exact_match'), - ('relatedMatch', 'related_match'), - ('closeMatch', 'close_match') + ("related", "related"), + ("broadMatch", "broad_match"), + ("narrowMatch", "narrow_match"), + ("exactMatch", "exact_match"), + ("relatedMatch", "related_match"), + ("closeMatch", "close_match"), ] @@ -68,6 +68,7 @@ # ###################################################################### + @reversion.register() class SkosConceptScheme(models.Model): """ @@ -78,94 +79,101 @@ class SkosConceptScheme(models.Model): Miles, Alistair, and Sean Bechhofer. "SKOS simple knowledge organization system reference. W3C recommendation (2009)." """ + title = models.CharField( max_length=300, help_text="Title for new concept scheme", - verbose_name="dc:title" + verbose_name="dc:title", ) title_lang = models.CharField( - max_length=3, blank=True, - verbose_name="dc:title language", default=DEFAULT_LANG, - help_text="Language of title given above" + max_length=3, + blank=True, + verbose_name="dc:title language", + default=DEFAULT_LANG, + help_text="Language of title given above", ) identifier = models.URLField( blank=True, help_text="URI to unambiguously identify current Concept Scheme" ) creator = models.TextField( - blank=True, verbose_name="dc:creator", + blank=True, + verbose_name="dc:creator", help_text="Person or organisation primarily responsible for making current concept scheme
" - "If more than one list all using a semicolon ;" + "If more than one list all using a semicolon ;", ) contributor = models.TextField( - blank=True, verbose_name="dc:contributor", + blank=True, + verbose_name="dc:contributor", help_text="Person or organisation that made contributions to the vocabulary
" - "If more than one list all using a semicolon ;" + "If more than one list all using a semicolon ;", ) language = models.TextField( - blank=True, verbose_name="dc:language", + blank=True, + verbose_name="dc:language", help_text="Language(s) used in concept scheme
" - "If more than one list all using a semicolon ;" + "If more than one list all using a semicolon ;", ) subject = models.TextField( - blank=True, verbose_name="dc:subject", + blank=True, + verbose_name="dc:subject", help_text="The subject of the vocabulary
" - "If more than one list all using a semicolon ;" - ) - version = models.CharField( - max_length=300, blank=True, - help_text="Current version" + "If more than one list all using a semicolon ;", ) + version = models.CharField(max_length=300, blank=True, help_text="Current version") publisher = models.CharField( - max_length=300, blank=True, + max_length=300, + blank=True, help_text="Organisation responsible for making the vocabulary available", - verbose_name="dc:publisher" + verbose_name="dc:publisher", ) license = models.CharField( - max_length=300, blank=True, + max_length=300, + blank=True, verbose_name="dct:license", - help_text="Information about license applied to the vocabulary" + help_text="Information about license applied to the vocabulary", ) owner = models.CharField( - max_length=300, blank=True, - help_text="Person or organisation that owns the rights for the vocabulary" + max_length=300, + blank=True, + help_text="Person or organisation that owns the rights for the vocabulary", ) relation = models.URLField( - blank=True, verbose_name="dc:relation", + blank=True, + verbose_name="dc:relation", help_text="Related resource or project
" - "E.g. in case of relation to a project, add link to a project website" + "E.g. in case of relation to a project, add link to a project website", ) coverage = models.TextField( - blank=True, verbose_name="dc:coverage", + blank=True, + verbose_name="dc:coverage", help_text="Spatial or temporal frame that the vocabulary relates to
" - "If more than one list all using a semicolon ;" - ) - legacy_id = models.CharField( - max_length=200, blank=True - ) - date_created = models.DateTimeField( - editable=False, default=timezone.now - ) - date_modified = models.DateTimeField( - editable=False, default=timezone.now + "If more than one list all using a semicolon ;", ) + legacy_id = models.CharField(max_length=200, blank=True) + date_created = models.DateTimeField(editable=False, default=timezone.now) + date_modified = models.DateTimeField(editable=False, default=timezone.now) date_issued = models.DateField( - blank=True, null=True, - help_text="Date of official publication of this concept scheme" + blank=True, + null=True, + help_text="Date of official publication of this concept scheme", ) created_by = models.ForeignKey( - User, related_name="skos_cs_created", - blank=True, null=True, - on_delete=models.SET_NULL + User, + related_name="skos_cs_created", + blank=True, + null=True, + on_delete=models.SET_NULL, ) curator = models.ManyToManyField( - User, related_name="skos_cs_curated", + User, + related_name="skos_cs_curated", blank=True, - help_text="The selected user(s) will be able to view and edit this Concept Scheme" + help_text="The selected user(s) will be able to view and edit this Concept Scheme", ) class Meta: - ordering = ['id'] - verbose_name = 'Concept Scheme' + ordering = ["id"] + verbose_name = "Concept Scheme" def save(self, *args, **kwargs): if not self.id: @@ -177,30 +185,30 @@ def save(self, *args, **kwargs): super(SkosConceptScheme, self).save(*args, **kwargs) def creator_as_list(self): - return self.creator.split(';') + return self.creator.split(";") def contributor_as_list(self): - return self.contributor.split(';') + return self.contributor.split(";") def language_as_list(self): - return self.language.split(';') + return self.language.split(";") def subject_as_list(self): - return self.subject.split(';') + return self.subject.split(";") def coverage_as_list(self): - return self.coverage.split(';') + return self.coverage.split(";") @classmethod def get_listview_url(self): - return reverse('vocabs:browse_schemes') + return reverse("vocabs:browse_schemes") @classmethod def get_createview_url(self): - return reverse('vocabs:skosconceptscheme_create') + return reverse("vocabs:skosconceptscheme_create") def get_absolute_url(self): - return reverse('vocabs:skosconceptscheme_detail', kwargs={'pk': self.id}) + return reverse("vocabs:skosconceptscheme_detail", kwargs={"pk": self.id}) def get_next(self): next = SkosConceptScheme.objects.filter(id__gt=self.id) @@ -209,7 +217,7 @@ def get_next(self): return False def get_prev(self): - prev = SkosConceptScheme.objects.filter(id__lt=self.id).order_by('-id') + prev = SkosConceptScheme.objects.filter(id__lt=self.id).order_by("-id") if prev: return prev.first().id return False @@ -222,25 +230,29 @@ def __str__(self): # Classes to store titles and descriptions for ConceptScheme ###################################################################### + class ConceptSchemeTitle(models.Model): """ A Class for ConceptScheme titles in other languages. """ + concept_scheme = models.ForeignKey( SkosConceptScheme, related_name="has_titles", verbose_name="skos:ConceptScheme", help_text="Which Skos:ConceptScheme current Title belongs to", - on_delete=models.CASCADE + on_delete=models.CASCADE, ) name = models.CharField( - max_length=500, verbose_name="dc:title", - help_text="Other title for new concept scheme" + max_length=500, + verbose_name="dc:title", + help_text="Other title for new concept scheme", ) language = models.CharField( - max_length=3, verbose_name="dc:title language", - help_text="Language of title given above" + max_length=3, + verbose_name="dc:title language", + help_text="Language of title given above", ) def __str__(self): @@ -252,20 +264,21 @@ class ConceptSchemeDescription(models.Model): A Class for ConceptScheme descriptions in other languages. """ + concept_scheme = models.ForeignKey( SkosConceptScheme, related_name="has_descriptions", verbose_name="skos:ConceptScheme", help_text="Which Skos:ConceptScheme current Description belongs to", - on_delete=models.CASCADE + on_delete=models.CASCADE, ) name = models.TextField( - verbose_name="dc:description", - help_text="Description of concept scheme" + verbose_name="dc:description", help_text="Description of concept scheme" ) language = models.CharField( - max_length=3, verbose_name="dc:description language", - help_text="Language of description given above" + max_length=3, + verbose_name="dc:description language", + help_text="Language of description given above", ) def __str__(self): @@ -277,20 +290,22 @@ class ConceptSchemeSource(models.Model): A Class for ConceptScheme source information. """ + concept_scheme = models.ForeignKey( SkosConceptScheme, related_name="has_sources", verbose_name="skos:ConceptScheme", help_text="Which Skos:ConceptScheme current source belongs to", - on_delete=models.CASCADE + on_delete=models.CASCADE, ) name = models.TextField( verbose_name="dc:source", - help_text="Verbal description of a concept scheme's source" + help_text="Verbal description of a concept scheme's source", ) language = models.CharField( - max_length=3, verbose_name="dc:source language", - help_text="Language of source given above" + max_length=3, + verbose_name="dc:source language", + help_text="Language of source given above", ) def __str__(self): @@ -303,6 +318,7 @@ def __str__(self): # ###################################################################### + @reversion.register() class SkosCollection(models.Model): """ @@ -315,52 +331,54 @@ class SkosCollection(models.Model): organization system reference. W3C recommendation (2009)." """ + name = models.CharField( - max_length=300, verbose_name="skos:prefLabel", - help_text="Collection label or name" + max_length=300, + verbose_name="skos:prefLabel", + help_text="Collection label or name", ) label_lang = models.CharField( - max_length=3, blank=True, + max_length=3, + blank=True, default=DEFAULT_LANG, verbose_name="skos:prefLabel language", - help_text="Language of preferred label given above" + help_text="Language of preferred label given above", ) # relation to SkosConceptScheme to inherit all objects permissions - scheme = models.ForeignKey(SkosConceptScheme, - related_name="has_collections", - verbose_name="skos:ConceptScheme", - help_text="Concept scheme that this collection belongs to", - on_delete=models.CASCADE - ) + scheme = models.ForeignKey( + SkosConceptScheme, + related_name="has_collections", + verbose_name="skos:ConceptScheme", + help_text="Concept scheme that this collection belongs to", + on_delete=models.CASCADE, + ) creator = models.TextField( - blank=True, verbose_name="dc:creator", + blank=True, + verbose_name="dc:creator", help_text="Person or organisation that created this collection
" - "If more than one list all using a semicolon ;" + "If more than one list all using a semicolon ;", ) contributor = models.TextField( - blank=True, verbose_name="dc:contributor", + blank=True, + verbose_name="dc:contributor", help_text="Person or organisation that made contributions to the collection
" - "If more than one list all using a semicolon ;" - ) - legacy_id = models.CharField( - max_length=200, blank=True + "If more than one list all using a semicolon ;", ) + legacy_id = models.CharField(max_length=200, blank=True) # meta autosaved fields - date_created = models.DateTimeField( - editable=False, default=timezone.now - ) - date_modified = models.DateTimeField( - editable=False, default=timezone.now - ) + date_created = models.DateTimeField(editable=False, default=timezone.now) + date_modified = models.DateTimeField(editable=False, default=timezone.now) created_by = models.ForeignKey( - User, related_name="skos_collection_created", - blank=True, null=True, - on_delete=models.SET_NULL + User, + related_name="skos_collection_created", + blank=True, + null=True, + on_delete=models.SET_NULL, ) class Meta: - ordering = ['id'] - verbose_name = 'Collection' + ordering = ["id"] + verbose_name = "Collection" def save(self, *args, **kwargs): if not self.id: @@ -370,14 +388,14 @@ def save(self, *args, **kwargs): @classmethod def get_listview_url(self): - return reverse('vocabs:browse_skoscollections') + return reverse("vocabs:browse_skoscollections") @classmethod def get_createview_url(self): - return reverse('vocabs:skoscollection_create') + return reverse("vocabs:skoscollection_create") def get_absolute_url(self): - return reverse('vocabs:skoscollection_detail', kwargs={'pk': self.id}) + return reverse("vocabs:skoscollection_detail", kwargs={"pk": self.id}) def get_next(self): next = SkosCollection.objects.filter(id__gt=self.id) @@ -386,7 +404,7 @@ def get_next(self): return False def get_prev(self): - prev = SkosCollection.objects.filter(id__lt=self.id).order_by('-id') + prev = SkosCollection.objects.filter(id__lt=self.id).order_by("-id") if prev: return prev.first().id return False @@ -395,10 +413,26 @@ def __str__(self): return self.name def creator_as_list(self): - return self.creator.split(';') + return self.creator.split(";") def contributor_as_list(self): - return self.contributor.split(';') + return self.contributor.split(";") + + def create_uri(self): + mcs = self.scheme.identifier + if mcs.endswith(VOCABS_SEPARATOR): + pass + else: + mcs = f"{mcs}{VOCABS_SEPARATOR}" + if self.legacy_id: + item_uri = f"{self.legacy_id}" + else: + if notation_for_uri: + tmp = slugify(self.notation, allow_unicode=False) + item_uri = f"{mcs}collection__{tmp}__{self.id}" + else: + item_uri = f"{mcs}collection{self.id}" + return item_uri ###################################################################### @@ -411,25 +445,28 @@ class CollectionLabel(models.Model): A Class for Collection labels/names in other languages. """ + collection = models.ForeignKey( SkosCollection, related_name="has_labels", verbose_name="skos:Collection", help_text="Which Skos:Collection current label belongs to", - on_delete=models.CASCADE + on_delete=models.CASCADE, ) name = models.CharField( - max_length=500, verbose_name="label", - help_text="Other label for this collection" + max_length=500, + verbose_name="label", + help_text="Other label for this collection", ) language = models.CharField( - max_length=3, verbose_name="language", - help_text="Language of label given above" + max_length=3, verbose_name="language", help_text="Language of label given above" ) label_type = models.CharField( - choices=LABEL_TYPES, verbose_name="label type", - default='altLabel', max_length=12, - help_text="Choose label type" + choices=LABEL_TYPES, + verbose_name="label type", + default="altLabel", + max_length=12, + help_text="Choose label type", ) def __str__(self): @@ -442,25 +479,27 @@ class CollectionNote(models.Model): for general documentation pusposes. """ + collection = models.ForeignKey( SkosCollection, related_name="has_notes", verbose_name="skos:Collection", help_text="Which Skos:Collection current documentary note belongs to", - on_delete=models.CASCADE + on_delete=models.CASCADE, ) name = models.TextField( verbose_name="documentary note", - help_text="Provide some information about this collection" + help_text="Provide some information about this collection", ) language = models.CharField( - max_length=3, verbose_name="language", - help_text="Language of note given above" + max_length=3, verbose_name="language", help_text="Language of note given above" ) note_type = models.CharField( - choices=NOTE_TYPES, verbose_name="note type", - default='note', max_length=15, - help_text="Choose note type" + choices=NOTE_TYPES, + verbose_name="note type", + default="note", + max_length=15, + help_text="Choose note type", ) def __str__(self): @@ -472,20 +511,22 @@ class CollectionSource(models.Model): A Class for Collection source information. """ + collection = models.ForeignKey( SkosCollection, related_name="has_sources", verbose_name="skos:Collection", help_text="Which Skos:Collection current source belongs to", - on_delete=models.CASCADE + on_delete=models.CASCADE, ) name = models.TextField( verbose_name="dc:source", - help_text="Verbal description of the collection's source" + help_text="Verbal description of the collection's source", ) language = models.CharField( - max_length=3, verbose_name="language", - help_text="Language of source given above" + max_length=3, + verbose_name="language", + help_text="Language of source given above", ) def __str__(self): @@ -498,6 +539,7 @@ def __str__(self): # ###################################################################### + @reversion.register() class SkosConcept(MPTTModel): """ @@ -508,16 +550,18 @@ class SkosConcept(MPTTModel): Miles, Alistair, and Sean Bechhofer. "SKOS simple knowledge organization system reference. W3C recommendation (2009)." """ + pref_label = models.CharField( max_length=300, verbose_name="skos:prefLabel", - help_text="Preferred label for concept" + help_text="Preferred label for concept", ) pref_label_lang = models.CharField( - max_length=3, blank=True, + max_length=3, + blank=True, verbose_name="skos:prefLabel language", help_text="Language of preferred label given above", - default=DEFAULT_LANG + default=DEFAULT_LANG, ) # relation to SkosConceptScheme to inherit all objects permissions scheme = models.ForeignKey( @@ -525,94 +569,103 @@ class SkosConcept(MPTTModel): verbose_name="skos:inScheme", related_name="has_concepts", on_delete=models.CASCADE, - help_text="Concept scheme to which this concept belongs" + help_text="Concept scheme to which this concept belongs", ) top_concept = models.BooleanField( - null=True, - help_text="Is this concept a top concept of concept scheme?" + null=True, help_text="Is this concept a top concept of concept scheme?" ) collection = models.ManyToManyField( - SkosCollection, blank=True, + SkosCollection, + blank=True, verbose_name="member of skos:Collection", help_text="Collection that this concept is a member of", related_name="has_members", ) notation = models.CharField( - max_length=300, blank=True, + max_length=300, + blank=True, verbose_name="skos:notation", help_text="A notation is a unique string used\ - to identify the concept in current vocabulary" + to identify the concept in current vocabulary", ) broader_concept = TreeForeignKey( - 'self', + "self", verbose_name="skos:broader", - blank=True, null=True, on_delete=models.CASCADE, + blank=True, + null=True, + on_delete=models.CASCADE, related_name="narrower_concepts", - help_text="Concept with a broader meaning that this concept inherits from" + help_text="Concept with a broader meaning that this concept inherits from", ) ################# semantic relationships via autocomplete ################# related = models.TextField( - blank=True, verbose_name="skos:related", - help_text="An associative relationship between two concepts" + blank=True, + verbose_name="skos:related", + help_text="An associative relationship between two concepts", ) broad_match = models.TextField( - blank=True, verbose_name="skos:broadMatch", - help_text="External concept with a broader meaning" + blank=True, + verbose_name="skos:broadMatch", + help_text="External concept with a broader meaning", ) narrow_match = models.TextField( - blank=True, verbose_name="skos:narrowMatch", - help_text="External concept with a narrower meaning" + blank=True, + verbose_name="skos:narrowMatch", + help_text="External concept with a narrower meaning", ) exact_match = models.TextField( - blank=True, verbose_name="skos:exactMatch", - help_text="External concept that can be used interchangeably and has the exact same meaning" + blank=True, + verbose_name="skos:exactMatch", + help_text="External concept that can be used interchangeably and has the exact same meaning", ) related_match = models.TextField( - blank=True, verbose_name="skos:relatedMatch", - help_text="External concept that has an associative relationship with this concept" + blank=True, + verbose_name="skos:relatedMatch", + help_text="External concept that has an associative relationship with this concept", ) close_match = models.TextField( - blank=True, verbose_name="skos:closeMatch", - help_text="External concept that has a similar meaning" + blank=True, + verbose_name="skos:closeMatch", + help_text="External concept that has a similar meaning", ) ########################################################################### # if using legacy_id as URI change it for URLField legacy_id = models.CharField(max_length=200, blank=True) creator = models.TextField( - blank=True, verbose_name="dc:creator", + blank=True, + verbose_name="dc:creator", help_text="Person or organisation that created this concept
" - "If more than one list all using a semicolon ;", - + "If more than one list all using a semicolon ;", ) contributor = models.TextField( - blank=True, verbose_name="dc:contributor", + blank=True, + verbose_name="dc:contributor", help_text="Person or organisation that made contributions to this concept
" - "If more than one list all using a semicolon ;" + "If more than one list all using a semicolon ;", ) needs_review = models.BooleanField( - null=True, - help_text="Check if this concept needs to be reviewed" + null=True, help_text="Check if this concept needs to be reviewed" ) date_created = models.DateTimeField( - editable=False, default=timezone.now, - verbose_name="dct:created" + editable=False, default=timezone.now, verbose_name="dct:created" ) date_modified = models.DateTimeField( - editable=False, default=timezone.now, - verbose_name="dct:modified" + editable=False, default=timezone.now, verbose_name="dct:modified" ) created_by = models.ForeignKey( - User, related_name="skos_concept_created", - blank=True, null=True, - on_delete=models.SET_NULL + User, + related_name="skos_concept_created", + blank=True, + null=True, + on_delete=models.SET_NULL, ) class Meta: - verbose_name = 'Concept' + verbose_name = "Concept" class MPTTMeta: - order_insertion_by = ['pref_label'] - parent_attr = 'broader_concept' + order_insertion_by = ["pref_label"] + parent_attr = "broader_concept" def get_vocabs_uri(self): return "{}{}".format("https://whatever", self.get_absolute_url) @@ -635,51 +688,55 @@ def save(self, *args, **kwargs): def create_uri(self): mcs = self.scheme.identifier + if mcs.endswith(VOCABS_SEPARATOR): + pass + else: + mcs = f"{mcs}{VOCABS_SEPARATOR}" if self.legacy_id: - concept_uri = f"{self.legacy_id}" + item_uri = f"{self.legacy_id}" else: if notation_for_uri: tmp = slugify(self.notation, allow_unicode=False) - concept_uri = f"{mcs}{VOCABS_SEPARATOR}concept__{tmp}__{self.id}" + item_uri = f"{mcs}concept__{tmp}__{self.id}" else: - concept_uri = f"{mcs}{VOCABS_SEPARATOR}concept{self.id}" - return concept_uri + item_uri = f"{mcs}concept{self.id}" + return item_uri # change for template tag def creator_as_list(self): - return self.creator.split(';') + return self.creator.split(";") def contributor_as_list(self): - return self.contributor.split(';') + return self.contributor.split(";") def broad_match_as_list(self): - return self.broad_match.split(',') + return self.broad_match.split(",") def related_as_list(self): - return self.related.split(',') + return self.related.split(",") def narrow_match_as_list(self): - return self.narrow_match.split(',') + return self.narrow_match.split(",") def exact_match_as_list(self): - return self.exact_match.split(',') + return self.exact_match.split(",") def related_match_as_list(self): - return self.related_match.split(',') + return self.related_match.split(",") def close_match_as_list(self): - return self.close_match.split(',') + return self.close_match.split(",") @classmethod def get_listview_url(self): - return reverse('vocabs:browse_vocabs') + return reverse("vocabs:browse_vocabs") @classmethod def get_createview_url(self): - return reverse('vocabs:skosconcept_create') + return reverse("vocabs:skosconcept_create") def get_absolute_url(self): - return reverse('vocabs:skosconcept_detail', kwargs={'pk': self.id}) + return reverse("vocabs:skosconcept_detail", kwargs={"pk": self.id}) def __str__(self): return self.pref_label @@ -695,25 +752,26 @@ class ConceptLabel(models.Model): A Class for Concept labels of any type. """ + concept = models.ForeignKey( SkosConcept, related_name="has_labels", verbose_name="skos:Concept", help_text="Which Skos:Concept current label belongs to", - on_delete=models.CASCADE + on_delete=models.CASCADE, ) name = models.CharField( - max_length=500, verbose_name="label", - help_text="Other label for this concept" + max_length=500, verbose_name="label", help_text="Other label for this concept" ) language = models.CharField( - max_length=3, verbose_name="language", - help_text="Language of label given above" + max_length=3, verbose_name="language", help_text="Language of label given above" ) label_type = models.CharField( - choices=LABEL_TYPES, verbose_name="label type", - default='altLabel', max_length=12, - help_text="Choose label type" + choices=LABEL_TYPES, + verbose_name="label type", + default="altLabel", + max_length=12, + help_text="Choose label type", ) def __str__(self): @@ -726,25 +784,27 @@ class ConceptNote(models.Model): for general documentation pusposes. """ + concept = models.ForeignKey( SkosConcept, related_name="has_notes", verbose_name="skos:Concept", help_text="Which Skos:Concept current documentary note belongs to", - on_delete=models.CASCADE + on_delete=models.CASCADE, ) name = models.TextField( verbose_name="documentary note", - help_text="Provide some information about this concept" + help_text="Provide some information about this concept", ) language = models.CharField( - max_length=3, verbose_name="language", - help_text="Language of note given above" + max_length=3, verbose_name="language", help_text="Language of note given above" ) note_type = models.CharField( - choices=NOTE_TYPES, verbose_name="note type", - default='note', max_length=15, - help_text="Choose note type" + choices=NOTE_TYPES, + verbose_name="note type", + default="note", + max_length=15, + help_text="Choose note type", ) def __str__(self): @@ -756,20 +816,21 @@ class ConceptSource(models.Model): A Class for Concept source information. """ + concept = models.ForeignKey( SkosConcept, related_name="has_sources", verbose_name="skos:Concept", help_text="Which Skos:Concept current source belongs to", - on_delete=models.CASCADE + on_delete=models.CASCADE, ) name = models.TextField( - verbose_name="dc:source", - help_text="Verbal description of the concept's source" + verbose_name="dc:source", help_text="Verbal description of the concept's source" ) language = models.CharField( - max_length=3, verbose_name="language", - help_text="Language of source given above" + max_length=3, + verbose_name="language", + help_text="Language of source given above", ) def __str__(self): @@ -795,73 +856,81 @@ def get_all_children(self, include_self=True): ############################################################################# -@receiver(post_save, sender=SkosConceptScheme, dispatch_uid="create_perms_cs_created_by") +@receiver( + post_save, sender=SkosConceptScheme, dispatch_uid="create_perms_cs_created_by" +) def create_perms_cs_created_by(sender, instance, **kwargs): - assign_perm('delete_skosconceptscheme', instance.created_by, instance) - assign_perm('change_skosconceptscheme', instance.created_by, instance) - assign_perm('view_skosconceptscheme', instance.created_by, instance) + assign_perm("delete_skosconceptscheme", instance.created_by, instance) + assign_perm("change_skosconceptscheme", instance.created_by, instance) + assign_perm("view_skosconceptscheme", instance.created_by, instance) -@receiver(post_save, sender=SkosCollection, dispatch_uid="create_perms_collection_created_by") +@receiver( + post_save, sender=SkosCollection, dispatch_uid="create_perms_collection_created_by" +) def create_perms_collection_created_by(sender, instance, **kwargs): - assign_perm('delete_skoscollection', instance.created_by, instance) - assign_perm('change_skoscollection', instance.created_by, instance) - assign_perm('view_skoscollection', instance.created_by, instance) + assign_perm("delete_skoscollection", instance.created_by, instance) + assign_perm("change_skoscollection", instance.created_by, instance) + assign_perm("view_skoscollection", instance.created_by, instance) for curator in instance.scheme.curator.all(): - assign_perm('delete_skoscollection', curator, instance) - assign_perm('change_skoscollection', curator, instance) - assign_perm('view_skoscollection', curator, instance) + assign_perm("delete_skoscollection", curator, instance) + assign_perm("change_skoscollection", curator, instance) + assign_perm("view_skoscollection", curator, instance) if curator is not instance.scheme.created_by: - assign_perm('delete_skoscollection', instance.scheme.created_by, instance) - assign_perm('change_skoscollection', instance.scheme.created_by, instance) - assign_perm('view_skoscollection', instance.scheme.created_by, instance) + assign_perm("delete_skoscollection", instance.scheme.created_by, instance) + assign_perm("change_skoscollection", instance.scheme.created_by, instance) + assign_perm("view_skoscollection", instance.scheme.created_by, instance) @receiver(post_save, sender=SkosConcept, dispatch_uid="create_perms_concept_created_by") def create_perms_concept_created_by(sender, instance, **kwargs): - assign_perm('delete_skosconcept', instance.created_by, instance) - assign_perm('change_skosconcept', instance.created_by, instance) - assign_perm('view_skosconcept', instance.created_by, instance) + assign_perm("delete_skosconcept", instance.created_by, instance) + assign_perm("change_skosconcept", instance.created_by, instance) + assign_perm("view_skosconcept", instance.created_by, instance) for curator in instance.scheme.curator.all(): - assign_perm('delete_skosconcept', curator, instance) - assign_perm('change_skosconcept', curator, instance) - assign_perm('view_skosconcept', curator, instance) + assign_perm("delete_skosconcept", curator, instance) + assign_perm("change_skosconcept", curator, instance) + assign_perm("view_skosconcept", curator, instance) if curator is not instance.scheme.created_by: - assign_perm('delete_skosconcept', instance.scheme.created_by, instance) - assign_perm('change_skosconcept', instance.scheme.created_by, instance) - assign_perm('view_skosconcept', instance.scheme.created_by, instance) + assign_perm("delete_skosconcept", instance.scheme.created_by, instance) + assign_perm("change_skosconcept", instance.scheme.created_by, instance) + assign_perm("view_skosconcept", instance.scheme.created_by, instance) ############### Adding new curator (user) to a Concept Scheme ################### ############### Only user who created a Concept Scheme can do it ################ -@receiver(m2m_changed, sender=SkosConceptScheme.curator.through, dispatch_uid="create_perms_curator") +@receiver( + m2m_changed, + sender=SkosConceptScheme.curator.through, + dispatch_uid="create_perms_curator", +) def create_perms_curator(sender, instance, **kwargs): - if kwargs['action'] == 'pre_add': - for curator in User.objects.filter(pk__in=kwargs['pk_set']): - assign_perm('view_skosconceptscheme', curator, instance) - assign_perm('change_skosconceptscheme', curator, instance) - assign_perm('delete_skosconceptscheme', curator, instance) + if kwargs["action"] == "pre_add": + for curator in User.objects.filter(pk__in=kwargs["pk_set"]): + assign_perm("view_skosconceptscheme", curator, instance) + assign_perm("change_skosconceptscheme", curator, instance) + assign_perm("delete_skosconceptscheme", curator, instance) for obj in instance.has_collections.all(): - assign_perm('view_' + obj.__class__.__name__.lower(), curator, obj) - assign_perm('change_' + obj.__class__.__name__.lower(), curator, obj) - assign_perm('delete_' + obj.__class__.__name__.lower(), curator, obj) + assign_perm("view_" + obj.__class__.__name__.lower(), curator, obj) + assign_perm("change_" + obj.__class__.__name__.lower(), curator, obj) + assign_perm("delete_" + obj.__class__.__name__.lower(), curator, obj) for obj in instance.has_concepts.all(): - assign_perm('view_' + obj.__class__.__name__.lower(), curator, obj) - assign_perm('change_' + obj.__class__.__name__.lower(), curator, obj) - assign_perm('delete_' + obj.__class__.__name__.lower(), curator, obj) - elif kwargs['action'] == 'post_remove': - for curator in User.objects.filter(pk__in=kwargs['pk_set']): - remove_perm('view_skosconceptscheme', curator, instance) - remove_perm('change_skosconceptscheme', curator, instance) + assign_perm("view_" + obj.__class__.__name__.lower(), curator, obj) + assign_perm("change_" + obj.__class__.__name__.lower(), curator, obj) + assign_perm("delete_" + obj.__class__.__name__.lower(), curator, obj) + elif kwargs["action"] == "post_remove": + for curator in User.objects.filter(pk__in=kwargs["pk_set"]): + remove_perm("view_skosconceptscheme", curator, instance) + remove_perm("change_skosconceptscheme", curator, instance) # if user removed from the curators list # he/she won't be able to access the objects he/she created within this CS for obj in instance.has_collections.all(): - remove_perm('view_' + obj.__class__.__name__.lower(), curator, obj) - remove_perm('change_' + obj.__class__.__name__.lower(), curator, obj) - remove_perm('delete_' + obj.__class__.__name__.lower(), curator, obj) + remove_perm("view_" + obj.__class__.__name__.lower(), curator, obj) + remove_perm("change_" + obj.__class__.__name__.lower(), curator, obj) + remove_perm("delete_" + obj.__class__.__name__.lower(), curator, obj) for obj in instance.has_concepts.all(): - remove_perm('view_' + obj.__class__.__name__.lower(), curator, obj) - remove_perm('change_' + obj.__class__.__name__.lower(), curator, obj) - remove_perm('delete_' + obj.__class__.__name__.lower(), curator, obj) + remove_perm("view_" + obj.__class__.__name__.lower(), curator, obj) + remove_perm("change_" + obj.__class__.__name__.lower(), curator, obj) + remove_perm("delete_" + obj.__class__.__name__.lower(), curator, obj) diff --git a/vocabs/rdf_utils.py b/vocabs/rdf_utils.py index d902528..b0fd6fa 100644 --- a/vocabs/rdf_utils.py +++ b/vocabs/rdf_utils.py @@ -35,7 +35,10 @@ def graph_construct_qs(results): for obj in results: # Creating Main Concept Scheme if obj.scheme: - main_concept_scheme = URIRef(obj.scheme.identifier) + if obj.scheme.legacy_id is not None: + main_concept_scheme = URIRef(obj.scheme.legacy_id) + else: + main_concept_scheme = URIRef(obj.scheme.identifier) g.add((main_concept_scheme, RDF.type, SKOS.ConceptScheme)) # Concept Scheme properties if obj.scheme.title: @@ -101,7 +104,7 @@ def graph_construct_qs(results): g.add((concept, SKOS.inScheme, main_concept_scheme)) if obj.collection.all(): for x in obj.collection.all(): - collection = URIRef(main_concept_scheme + VOCABS_SEPARATOR + "collection" + str(x.id)) + collection = URIRef(x.create_uri()) g.add((collection, RDF.type, SKOS.Collection)) g.add((collection, DCT.created, Literal(x.date_created, datatype=XSD.dateTime))) g.add((collection, DCT.modified, Literal(x.date_modified, datatype=XSD.dateTime))) @@ -156,7 +159,7 @@ def graph_construct_qs(results): ( collection, SKOS.member, - URIRef(main_concept_scheme + VOCABS_SEPARATOR + "concept" + str(y.id)) + URIRef(y.create_uri()) ) ) # Concept properties @@ -198,27 +201,10 @@ def graph_construct_qs(results): g.add((concept, SKOS.topConceptOf, main_concept_scheme)) # modelling broader/narrower relationships if obj.broader_concept: - if obj.broader_concept.legacy_id: - g.add((concept, SKOS.broader, URIRef(obj.broader_concept.legacy_id))) - else: - g.add( - ( - concept, - SKOS.broader, - URIRef(main_concept_scheme + VOCABS_SEPARATOR + "concept" + str(obj.broader_concept.id))) - ) + g.add((concept, SKOS.broader, URIRef(obj.broader_concept.create_uri()))) if obj.narrower_concepts.all(): for x in obj.narrower_concepts.all(): - if x.legacy_id: - g.add((concept, SKOS.narrower, URIRef(x.legacy_id))) - else: - g.add( - ( - concept, - SKOS.narrower, - URIRef(main_concept_scheme + VOCABS_SEPARATOR + "concept" + str(x.id)) - ) - ) + g.add((concept, SKOS.narrower, URIRef(x.create_uri()))) # modelling external matches # skos:related if obj.related: