From a408ab859e9aeff42809e21b65bbe9926b4a6956 Mon Sep 17 00:00:00 2001 From: Calum Mackervoy <c.mackervoy@gmail.com> Date: Wed, 22 Jul 2020 17:59:04 +0000 Subject: [PATCH] update: viewset-serializer decoupling --- djangoldp/permissions.py | 4 ++-- djangoldp/serializers.py | 19 ++++++++++++++++--- djangoldp/views.py | 15 +++++++++++---- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/djangoldp/permissions.py b/djangoldp/permissions.py index dffd104a..5d888fe7 100644 --- a/djangoldp/permissions.py +++ b/djangoldp/permissions.py @@ -123,7 +123,7 @@ class LDPPermissions(DjangoObjectPermissions): # compare them with the permissions I have for perm in perms: - if not perm.split('.')[1].split('_')[0] in user_perms: + if not perm.split('.')[-1].split('_')[0] in user_perms: return False return True @@ -146,7 +146,7 @@ class LDPPermissions(DjangoObjectPermissions): # compare them with the permissions I have for perm in perms: - if not perm.split('.')[1].split('_')[0] in user_perms: + if not perm.split('.')[-1].split('_')[0] in user_perms: return False return True diff --git a/djangoldp/serializers.py b/djangoldp/serializers.py index cfbbe047..b10fe109 100644 --- a/djangoldp/serializers.py +++ b/djangoldp/serializers.py @@ -15,7 +15,7 @@ from rest_framework.exceptions import ValidationError from rest_framework.fields import SkipField, empty, ReadOnlyField from rest_framework.fields import get_error_detail, set_value from rest_framework.relations import HyperlinkedRelatedField, ManyRelatedField, MANY_RELATION_KWARGS, Hyperlink -from rest_framework.serializers import HyperlinkedModelSerializer, ListSerializer, ModelSerializer +from rest_framework.serializers import HyperlinkedModelSerializer, ListSerializer, ModelSerializer, LIST_SERIALIZER_KWARGS from rest_framework.settings import api_settings from rest_framework.utils import model_meta from rest_framework.utils.field_mapping import get_nested_relation_kwargs @@ -481,8 +481,21 @@ class LDPSerializer(HyperlinkedModelSerializer): @classmethod def many_init(cls, *args, **kwargs): - kwargs['child'] = cls(**kwargs) - serializer = ContainerSerializer(*args, **kwargs) + allow_empty = kwargs.pop('allow_empty', None) + child_serializer = cls(*args, **kwargs) + list_kwargs = { + 'child': child_serializer, + } + if allow_empty is not None: + list_kwargs['allow_empty'] = allow_empty + list_kwargs.update({ + key: value for key, value in kwargs.items() + if key in LIST_SERIALIZER_KWARGS + }) + meta = getattr(cls, 'Meta', None) + list_serializer_class = getattr(meta, 'list_serializer_class', ContainerSerializer) + serializer = list_serializer_class(*args, **list_kwargs) + if 'context' in kwargs and getattr(kwargs['context']['view'], 'nested_field', None) is not None: serializer.id = '{}{}/'.format(serializer.id, kwargs['context']['view'].nested_field) elif 'context' in kwargs: diff --git a/djangoldp/views.py b/djangoldp/views.py index 97da3969..bae30f1b 100644 --- a/djangoldp/views.py +++ b/djangoldp/views.py @@ -305,6 +305,10 @@ class LDPViewSetGenerator(ModelViewSet): lookup_group = r'\d' if lookup_field == 'pk' else r'[\w\-\.]' return r'(?P<{}>{}+)/'.format(lookup_field, lookup_group) + @classonlymethod + def nested_urls(cls, nested_field, **kwargs): + return LDPNestedViewSet.nested_urls(nested_field, **kwargs) + @classonlymethod def urls(cls, **kwargs): '''constructs urls list for model passed in kwargs''' @@ -322,7 +326,7 @@ class LDPViewSetGenerator(ModelViewSet): # append nested fields to the urls list for field in kwargs.get('nested_fields') or cls.nested_fields: - urls.append(url('^' + detail_expr + field + '/', LDPNestedViewSet.nested_urls(field, **kwargs))) + urls.append(url('^' + detail_expr + field + '/', cls.nested_urls(field, **kwargs))) return include(urls) @@ -336,6 +340,7 @@ class LDPViewSet(LDPViewSetGenerator): parser_classes = (JSONLDParser,) authentication_classes = (NoCSRFAuthentication,) filter_backends = [LocalObjectOnContainerPathBackend] + write_serializer_class = None def __init__(self, **kwargs): super().__init__(**kwargs) @@ -346,8 +351,10 @@ class LDPViewSet(LDPViewSetGenerator): if hasattr(p, 'filter_class') and p.filter_class: self.filter_backends.append(p.filter_class) - self.serializer_class = self.build_read_serializer() - self.write_serializer_class = self.build_write_serializer() + if self.serializer_class is None: + self.serializer_class = self.build_read_serializer() + if self.write_serializer_class is None: + self.write_serializer_class = self.build_write_serializer() def build_read_serializer(self): model_name = self.model._meta.object_name.lower() @@ -422,7 +429,7 @@ class LDPViewSet(LDPViewSetGenerator): deserializing input, and for serializing output. """ serializer_class = self.get_write_serializer_class() - kwargs['context'] = self.get_serializer_context() + kwargs.setdefault('context', self.get_serializer_context()) return serializer_class(*args, **kwargs) def get_write_serializer_class(self): -- GitLab