Skip to content

Commit

Permalink
feat(generic): add a GenericModelCidocSerializer
Browse files Browse the repository at this point in the history
This serializer should provide a basis for CIDOC serializers as well as
a fallback for models that have no CIDOC serializer configured.
  • Loading branch information
b1rger committed Dec 19, 2024
1 parent e80e62e commit c253e4f
Showing 1 changed file with 63 additions and 0 deletions.
63 changes: 63 additions & 0 deletions apis_core/generic/serializers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404
from rdflib import Graph, Literal, Namespace, URIRef
from rdflib.namespace import GEO, OWL, RDF, RDFS
from rest_framework.reverse import reverse
from rest_framework.serializers import (
BaseSerializer,
CharField,
HyperlinkedModelSerializer,
HyperlinkedRelatedField,
Expand All @@ -10,6 +13,8 @@
SerializerMethodField,
)

from apis_core.utils.settings import apis_base_uri, rdf_namespace_prefix


class GenericHyperlinkedRelatedField(HyperlinkedRelatedField):
def get_url(self, obj, view_name, request, format):
Expand Down Expand Up @@ -87,3 +92,61 @@ def get_content_type_key(self, obj) -> str:
def get_content_type_name(self, obj) -> str:
content_type = ContentType.objects.get_for_model(obj)
return content_type.name


class GenericModelCidocSerializer(BaseSerializer):
def __init__(self, *args, **kwargs):
self.base_uri = f"{apis_base_uri()}"
self.rdf_nsp_base = rdf_namespace_prefix()
self.appellation_nsp_prefix = f"{self.rdf_nsp_base}-appellation"
self.attr_nsp_prefix = f"{self.rdf_nsp_base}-attr"
super().__init__(*args, **kwargs)

def to_representation(self, instance):
g = Graph()
content_type = ContentType.objects.get_for_model(instance)

crm_namespace = Namespace("http://www.cidoc-crm.org/cidoc-crm/")
g.namespace_manager.bind("crm", crm_namespace, replace=True)
g.namespace_manager.bind("owl", OWL, replace=True)
g.namespace_manager.bind("geo", GEO, replace=True)

appellation_namespace = Namespace(f"{self.base_uri}/appellation/")
g.namespace_manager.bind(
self.appellation_nsp_prefix, appellation_namespace, replace=True
)
attributes_namespace = Namespace(f"{self.base_uri}/attributes/")
g.namespace_manager.bind(
self.attr_nsp_prefix, attributes_namespace, replace=True
)

self.instance_nsp_prefix = f"{self.rdf_nsp_base}-{content_type.name.lower()}"
instance_namespace = Namespace(self.base_uri + instance.get_listview_url())
g.namespace_manager.bind(self.instance_nsp_prefix, instance_namespace)

self.instance_uri = URIRef(instance_namespace[str(instance.id)])

# Add sameAs links
for uri in instance.uri_set.all():
uri_ref = URIRef(uri.uri)
g.add((self.instance_uri, OWL.sameAs, uri_ref))

# Add properties
self.appellation_uri = URIRef(appellation_namespace[str(instance.id)])
g.add(
(
self.appellation_uri,
RDF.type,
crm_namespace.E33_E41_Linguistic_Appellation,
)
)
g.add(
(
self.instance_uri,
crm_namespace.P1_is_identified_by,
self.appellation_uri,
)
)
g.add((self.appellation_uri, RDFS.label, Literal(str(instance))))

return g

0 comments on commit c253e4f

Please sign in to comment.