From 8584976af0aa74dd4532b3a381165cab973bd7a3 Mon Sep 17 00:00:00 2001 From: Calum Mackervoy <c.mackervoy@gmail.com> Date: Fri, 13 Aug 2021 17:00:31 +0200 Subject: [PATCH] feature: barebones simple LDPSerializer alternative --- djangoldp/serializers_new.py | 88 ++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 djangoldp/serializers_new.py diff --git a/djangoldp/serializers_new.py b/djangoldp/serializers_new.py new file mode 100644 index 00000000..a4d89bd3 --- /dev/null +++ b/djangoldp/serializers_new.py @@ -0,0 +1,88 @@ +from django.conf import settings +from rest_framework.relations import HyperlinkedRelatedField, RelatedField +from rest_framework.serializers import Serializer +from djangoldp.models import Model +from djangoldp.serializers import _serialize_rdf_fields + + +class NewJsonLDRelatedField(RelatedField): + ''' + Requirements for use: + * model has a urlid field (URL string) + ''' + def to_representation(self, instance): + data = { + '@id': instance.urlid + } + + rdf_type = Model.get_meta(instance, 'rdf_type', None) + if rdf_type is not None: + data.update({'@type': rdf_type}) + + return data + + def to_internal_value(self, data): + # TODO: ... + # you have JSON-LD data, you want model instance + # main issue is not knowing the type + # the connected instance MUST exist + # the connected instance MAY be foreign + if '@type' in data: + model_class = Model.get_subclass_with_rdf_type(data['@type']) + return model_class.objects.get(urlid=data['@id']) + + +class NewLDPSerializer(Serializer): + ''' + Requirements for use: + * model has a urlid field, used as a unique identifier on the instance + ''' + + def external_instance_to_representation(self, instance): + '''called by to_representation when serializing external instances''' + data = {'@id': instance.urlid} + return _serialize_rdf_fields(instance, data) + + def to_representation(self, instance): + # external Models should only be returned with rdf values + if Model.is_external(instance): + return self.external_instance_to_representation(instance) + + data = super().to_representation(instance) + + ''' + slug_field = Model.slug_field(obj) + for field in data: + if isinstance(data[field], dict) and '@id' in data[field]: + data[field]['@id'] = data[field]['@id'].format(Model.container_id(obj), str(getattr(obj, slug_field))) + ''' + + # prioritise urlid field over generated @id + if 'urlid' in data and data['urlid'] is not None: + data['@id'] = data.pop('urlid')['@id'] + # TODO: raise error or try to treat it? + '''if not '@id' in data: + try: + data['@id'] = '{}{}'.format(settings.SITE_URL, Model.resource(obj)) + except AttributeError, NoReverseMatch: + pass''' + + data = _serialize_rdf_fields(instance, data, include_context=True) + + # permissions serialization: depends on request! + ''' + if hasattr(obj, 'get_model_class'): + model_class = obj.get_model_class() + else: + model_class = type(obj) + data['permissions'] = _serialize_object_permissions( + Model.get_permissions(model_class, self.context['request'], self.context['view'], obj)) + ''' + + return data + + def to_internal_value(self, data): + if '@id' in data and not 'urlid' in data: + data['urlid'] = data.pop('@id') + + return super().to_internal_value(data) -- GitLab