From 6a4bafc79ffa9043ddb15ff698969cd0b3585dc3 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste <bleme@pm.me> Date: Thu, 14 Mar 2019 15:22:02 +0100 Subject: [PATCH] update: depth and many_depth configurable on Model --- djangoldp/__init__.py | 2 +- djangoldp/models.py | 2 ++ djangoldp/serializers.py | 23 ++++++++++++++++++++--- djangoldp/tests/models.py | 17 ++++++++--------- djangoldp/tests/tests_save.py | 10 +++++----- djangoldp/tests/tests_update.py | 10 +++++----- djangoldp/views.py | 4 ++-- 7 files changed, 43 insertions(+), 25 deletions(-) diff --git a/djangoldp/__init__.py b/djangoldp/__init__.py index 8c3166a1..7deb3ab1 100644 --- a/djangoldp/__init__.py +++ b/djangoldp/__init__.py @@ -1,4 +1,4 @@ from django.db.models import options __version__ = '0.0.0' -options.DEFAULT_NAMES += ('lookup_field', 'rdf_type', 'rdf_context', 'auto_author', 'view_set', 'container_path', 'permission_classes', 'serializer_fields', 'nested_fields') \ No newline at end of file +options.DEFAULT_NAMES += ('lookup_field', 'rdf_type', 'rdf_context', 'auto_author', 'view_set', 'container_path', 'permission_classes', 'serializer_fields', 'nested_fields', 'depth', 'many_depth') \ No newline at end of file diff --git a/djangoldp/models.py b/djangoldp/models.py index e8a79806..f08147cd 100644 --- a/djangoldp/models.py +++ b/djangoldp/models.py @@ -54,6 +54,8 @@ class Model(models.Model): class Meta: default_permissions = ('add', 'change', 'delete', 'view', 'control') abstract = True + depth = 1 + many_depth = 0 @classmethod def resolve_id(cls, id): diff --git a/djangoldp/serializers.py b/djangoldp/serializers.py index f6a8c821..01163f53 100644 --- a/djangoldp/serializers.py +++ b/djangoldp/serializers.py @@ -225,6 +225,11 @@ class LDPSerializer(HyperlinkedModelSerializer): return data + def build_field(self, field_name, info, model_class, nested_depth): + nested_depth = self.compute_depth(nested_depth, model_class) + + return super().build_field(field_name, info, model_class, nested_depth) + def build_standard_field(self, field_name, model_field): class JSonLDStandardField: parent_view_name = None @@ -253,6 +258,8 @@ class LDPSerializer(HyperlinkedModelSerializer): return type(field_class.__name__ + 'Valued', (JSonLDStandardField, field_class), {}), field_kwargs def build_nested_field(self, field_name, relation_info, nested_depth): + nested_depth = self.compute_depth(nested_depth, self.Meta.model) + class NestedLDPSerializer(self.__class__): class Meta: @@ -321,11 +328,21 @@ class LDPSerializer(HyperlinkedModelSerializer): kwargs['required'] = False return NestedLDPSerializer, kwargs + @classmethod + def compute_depth(cls, depth, model_class, name='depth'): + try: + model_depth = getattr(model_class._meta, 'depth', getattr(model_class.Meta, 'depth', 10)) + depth = min(depth, int(model_depth)) + except AttributeError: + depth = min(depth, int(getattr(model_class._meta, 'depth', 1))) + + return depth + @classmethod def many_init(cls, *args, **kwargs): kwargs['child'] = cls(**kwargs) try: - cls.Meta.depth = kwargs['context']['view'].many_depth + cls.Meta.depth = cls.compute_depth(kwargs['context']['view'].many_depth, cls.Meta.model, 'many_depth') except KeyError: pass return ContainerSerializer(*args, **kwargs) @@ -359,9 +376,9 @@ class LDPSerializer(HyperlinkedModelSerializer): return instance def attach_related_object(self, instance, validated_data): - ModelClass = self.Meta.model + model_class = self.Meta.model - info = model_meta.get_field_info(ModelClass) + info = model_meta.get_field_info(model_class) many_to_many = {} for field_name, relation_info in info.relations.items(): if relation_info.to_many and relation_info.reverse and not (field_name in validated_data): diff --git a/djangoldp/tests/models.py b/djangoldp/tests/models.py index 43e56d66..e576eadb 100644 --- a/djangoldp/tests/models.py +++ b/djangoldp/tests/models.py @@ -1,7 +1,5 @@ from django.conf import settings from django.db import models -from django.db.models.signals import pre_save -from django.dispatch import receiver from djangoldp.models import Model @@ -11,9 +9,8 @@ class Skill(Model): obligatoire = models.CharField(max_length=255) slug = models.SlugField(blank=True, null=True, unique=True) - class Meta: - serializer_fields=["@id", "title"] + serializer_fields = ["@id", "title"] lookup_field = 'slug' @@ -23,8 +20,8 @@ class JobOffer(Model): slug = models.SlugField(blank=True, null=True, unique=True) class Meta: - nested_fields=["skills"] - container_path="job-offers/" + nested_fields = ["skills"] + container_path = "job-offers/" lookup_field = 'slug' @@ -51,6 +48,10 @@ class LDPDummy(Model): class Invoice(Model): title = models.CharField(max_length=255, blank=True, null=True) + class Meta: + depth = 2 + nested_fields = ["batches"] + class Batch(Model): invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE, related_name='batches') @@ -58,6 +59,7 @@ class Batch(Model): class Meta: serializer_fields = ['@id', 'title', 'invoice', 'tasks'] + nested_fields = ["tasks"] class Task(models.Model): @@ -66,6 +68,3 @@ class Task(models.Model): class Meta: serializer_fields = ['@id', 'title', 'batch'] - - - diff --git a/djangoldp/tests/tests_save.py b/djangoldp/tests/tests_save.py index 0d7b70b9..27630999 100644 --- a/djangoldp/tests/tests_save.py +++ b/djangoldp/tests/tests_save.py @@ -53,7 +53,7 @@ class Save(TestCase): ]} } - meta_args = {'model': JobOffer, 'depth': 1, 'fields': ("@id", "title", "skills", "slug")} + meta_args = {'model': JobOffer, 'depth': 2, 'fields': ("@id", "title", "skills", "slug")} meta_class = type('Meta', (), meta_args) serializer_class = type(LDPSerializer)('JobOfferSerializer', (LDPSerializer,), {'Meta': meta_class}) @@ -73,7 +73,7 @@ class Save(TestCase): }, ]} - meta_args = {'model': JobOffer, 'depth': 1, 'fields': ("@id", "title", "skills")} + meta_args = {'model': JobOffer, 'depth': 2, 'fields': ("@id", "title", "skills")} meta_class = type('Meta', (), meta_args) serializer_class = type(LDPSerializer)('JobOfferSerializer', (LDPSerializer,), {'Meta': meta_class}) @@ -95,7 +95,7 @@ class Save(TestCase): {"@id": "_.123", "title": "skill3 NEW", "obligatoire": "obligatoire"}, ]} - meta_args = {'model': JobOffer, 'depth': 1, 'fields': ("@id", "title", "skills")} + meta_args = {'model': JobOffer, 'depth': 2, 'fields': ("@id", "title", "skills")} meta_class = type('Meta', (), meta_args) serializer_class = type(LDPSerializer)('JobOfferSerializer', (LDPSerializer,), {'Meta': meta_class}) @@ -112,7 +112,7 @@ class Save(TestCase): skill2 = Skill.objects.create(title="skill2", obligatoire="obligatoire") job = {"title": "job test"} - meta_args = {'model': JobOffer, 'depth': 1, 'fields': ("@id", "title", "skills")} + meta_args = {'model': JobOffer, 'depth': 2, 'fields': ("@id", "title", "skills")} meta_class = type('Meta', (), meta_args) serializer_class = type(LDPSerializer)('JobOfferSerializer', (LDPSerializer,), {'Meta': meta_class}) @@ -130,7 +130,7 @@ class Save(TestCase): job = JobOffer.objects.create(title="job test") skill = {"title": "new SKILL"} - meta_args = {'model': Skill, 'depth': 1, 'fields': ("@id", "title")} + meta_args = {'model': Skill, 'depth': 2, 'fields': ("@id", "title")} meta_class = type('Meta', (), meta_args) serializer_class = type(LDPSerializer)('SkillSerializer', (LDPSerializer,), {'Meta': meta_class}) diff --git a/djangoldp/tests/tests_update.py b/djangoldp/tests/tests_update.py index 19c96eff..9d19ea91 100644 --- a/djangoldp/tests/tests_update.py +++ b/djangoldp/tests/tests_update.py @@ -24,7 +24,7 @@ class Update(TestCase): ]} } - meta_args = {'model': JobOffer, 'depth': 1, 'fields': ("@id", "title", "skills")} + meta_args = {'model': JobOffer, 'depth': 2, 'fields': ("@id", "title", "skills")} meta_class = type('Meta', (), meta_args) serializer_class = type(LDPSerializer)('JobOfferSerializer', (LDPSerializer,), {'Meta': meta_class}) @@ -73,7 +73,7 @@ class Update(TestCase): ] } - meta_args = {'model': JobOffer, 'depth': 1, 'fields': ("@id", "title", "skills")} + meta_args = {'model': JobOffer, 'depth': 2, 'fields': ("@id", "title", "skills")} meta_class = type('Meta', (), meta_args) serializer_class = type(LDPSerializer)('JobOfferSerializer', (LDPSerializer,), {'Meta': meta_class}) @@ -128,7 +128,7 @@ class Update(TestCase): ] } - meta_args = {'model': JobOffer, 'depth': 1, 'fields': ("@id", "title", "skills")} + meta_args = {'model': JobOffer, 'depth': 2, 'fields': ("@id", "title", "skills")} meta_class = type('Meta', (), meta_args) serializer_class = type(LDPSerializer)('JobOfferSerializer', (LDPSerializer,), {'Meta': meta_class}) @@ -171,7 +171,7 @@ class Update(TestCase): ] } - meta_args = {'model': Thread, 'depth': 1, 'fields': ("@id", "description", "message_set")} + meta_args = {'model': Thread, 'depth': 2, 'fields': ("@id", "description", "message_set")} meta_class = type('Meta', (), meta_args) serializer_class = type(LDPSerializer)('ThreadSerializer', (LDPSerializer,), {'Meta': meta_class}) @@ -235,7 +235,7 @@ class Update(TestCase): ] } - meta_args = {'model': Thread, 'depth': 1, 'fields': ("@id", "description", "message_set")} + meta_args = {'model': Thread, 'depth': 2, 'fields': ("@id", "description", "message_set")} meta_class = type('Meta', (), meta_args) serializer_class = type(LDPSerializer)('ThreadSerializer', (LDPSerializer,), {'Meta': meta_class}) diff --git a/djangoldp/views.py b/djangoldp/views.py index f3a08499..0af35f86 100644 --- a/djangoldp/views.py +++ b/djangoldp/views.py @@ -89,8 +89,8 @@ class LDPViewSet(LDPViewSetGenerator): """An automatically generated viewset that serves models following the Linked Data Platform convention""" fields = None exclude = None - depth = 1 - many_depth = 0 + depth = 2 + many_depth = 1 renderer_classes = (JSONLDRenderer,) parser_classes = (JSONLDParser,) authentication_classes = (NoCSRFAuthentication,) -- GitLab