From 3fd6b5018c599c95327119ef5454a6365d177790 Mon Sep 17 00:00:00 2001 From: Calum Mackervoy <c.mackervoy@gmail.com> Date: Wed, 15 Jul 2020 14:31:49 +0000 Subject: [PATCH] feature: serializer_fields_exclude --- README.md | 18 ++++++++++++++++++ djangoldp/__init__.py | 4 ++-- djangoldp/tests/djangoldp_urls.py | 3 ++- djangoldp/tests/models.py | 2 ++ djangoldp/tests/tests_get.py | 17 +++++++++++++++-- djangoldp/views.py | 2 +- 6 files changed, 40 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6d3c4299..94f9d291 100644 --- a/README.md +++ b/README.md @@ -411,6 +411,24 @@ class Todo(Model): Only `name` will be serialized +### serializer_fields_exclude + +```python +from djangoldp.models import Model + +class Todo(Model): + name = models.CharField(max_length=255) + deadline = models.DateTimeField() + + class Meta: + serializer_fields_exclude = ['name'] + +``` + +Only `deadline` will be serialized + +This is achieved when `LDPViewSet` sets the `exclude` property on the serializer in `build_serializer` method. Note that if you use a custom viewset which does not extend LDPSerializer then you will need to set this property yourself + ### nested_fields -- DEPRECIATED Set on a model to auto-generate viewsets and containers for nested relations (e.g. `/circles/<pk>/members/`) diff --git a/djangoldp/__init__.py b/djangoldp/__init__.py index ac5b5247..cf33475a 100644 --- a/djangoldp/__init__.py +++ b/djangoldp/__init__.py @@ -3,6 +3,6 @@ from django.db.models import options __version__ = '0.0.0' options.DEFAULT_NAMES += ( 'lookup_field', 'rdf_type', 'rdf_context', 'auto_author', 'auto_author_field', 'owner_field', 'view_set', - 'container_path', 'permission_classes', 'serializer_fields', 'nested_fields', 'nested_fields_exclude', 'depth', - 'anonymous_perms', 'authenticated_perms', 'owner_perms') + 'container_path', 'permission_classes', 'serializer_fields', 'serializer_fields_exclude', 'nested_fields', + 'nested_fields_exclude', 'depth', 'anonymous_perms', 'authenticated_perms', 'owner_perms') default_app_config = 'djangoldp.apps.DjangoldpConfig' diff --git a/djangoldp/tests/djangoldp_urls.py b/djangoldp/tests/djangoldp_urls.py index c13aad61..4766fedf 100644 --- a/djangoldp/tests/djangoldp_urls.py +++ b/djangoldp/tests/djangoldp_urls.py @@ -2,13 +2,14 @@ from django.conf import settings from django.conf.urls import url, include from djangoldp.permissions import LDPPermissions -from djangoldp.tests.models import Skill, JobOffer, Message, Conversation, Dummy, PermissionlessDummy, Task +from djangoldp.tests.models import Skill, JobOffer, Message, Conversation, Dummy, PermissionlessDummy, Task, DateModel from djangoldp.views import LDPViewSet urlpatterns = [ url(r'^messages/', LDPViewSet.urls(model=Message, permission_classes=[LDPPermissions], fields=["@id", "text", "conversation"], nested_fields=['conversation'])), url(r'^conversations/', LDPViewSet.urls(model=Conversation, nested_fields=["message_set"], permission_classes=[LDPPermissions])), url(r'^tasks/', LDPViewSet.urls(model=Task, permission_classes=[LDPPermissions])), + url(r'^dates/', LDPViewSet.urls(model=DateModel, permission_classes=[LDPPermissions])), url(r'^dummys/', LDPViewSet.urls(model=Dummy, permission_classes=[LDPPermissions], lookup_field='slug',)), url(r'^permissionless-dummys/', LDPViewSet.urls(model=PermissionlessDummy, permission_classes=[LDPPermissions], lookup_field='slug',)), ] diff --git a/djangoldp/tests/models.py b/djangoldp/tests/models.py index 9a3acce5..6c2b5b84 100644 --- a/djangoldp/tests/models.py +++ b/djangoldp/tests/models.py @@ -223,10 +223,12 @@ class Project(Model): class DateModel(Model): + excluded = models.CharField(max_length=255, null=True, default='test') value = models.DateField() class Meta(Model.Meta): rdf_type = "hd:date" + serializer_fields_exclude = ['excluded'] class DateChild(Model): diff --git a/djangoldp/tests/tests_get.py b/djangoldp/tests/tests_get.py index adda7c7b..a32a80bd 100644 --- a/djangoldp/tests/tests_get.py +++ b/djangoldp/tests/tests_get.py @@ -1,8 +1,8 @@ from rest_framework.test import APIRequestFactory, APIClient, APITestCase - +from datetime import datetime from rest_framework.test import APIRequestFactory, APIClient, APITestCase -from djangoldp.tests.models import Post, Invoice, JobOffer, Skill, Batch +from djangoldp.tests.models import Post, Invoice, JobOffer, Skill, Batch, DateModel class TestGET(APITestCase): @@ -88,3 +88,16 @@ class TestGET(APITestCase): self.assertEqual(response.status_code, 200) self.assertEquals(response.data['@id'], 'http://happy-dev.fr/invoices/{}/batches/'.format(invoice.pk)) self.assertEquals(len(response.data['ldp:contains']), 2) + + def test_serializer_excludes(self): + date = DateModel.objects.create(excluded='test', value=datetime.now()) + response = self.client.get('/dates/{}/'.format(date.pk), content_type='application/ld+json') + self.assertEqual(response.status_code, 200) + self.assertNotIn('excluded', response.data.keys()) + + def test_serializer_excludes_serializer_fields_set_also(self): + setattr(DateModel._meta, 'serializer_fields', ['value', 'excluded']) + date = DateModel.objects.create(excluded='test', value=datetime.now()) + response = self.client.get('/dates/{}/'.format(date.pk), content_type='application/ld+json') + self.assertEqual(response.status_code, 200) + self.assertNotIn('excluded', response.data.keys()) diff --git a/djangoldp/views.py b/djangoldp/views.py index 6a2dfb8b..7c0e7df9 100644 --- a/djangoldp/views.py +++ b/djangoldp/views.py @@ -368,7 +368,7 @@ class LDPViewSet(LDPViewSetGenerator): if self.fields: meta_args['fields'] = self.fields else: - meta_args['exclude'] = self.exclude or () + meta_args['exclude'] = self.exclude or Model.get_meta(self.model, 'serializer_fields_exclude') or () meta_class = type('Meta', (), meta_args) from djangoldp.serializers import LDPSerializer -- GitLab