Skip to content
Snippets Groups Projects
Commit 5ce49f46 authored by Jean-Baptiste's avatar Jean-Baptiste
Browse files

update: split serializer (read / write)

parent 02cb2a21
No related branches found
No related tags found
1 merge request!81Resolve "Split LDPSerializer (Read / write)"
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', 'depth', 'many_depth')
\ 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')
......@@ -66,7 +66,6 @@ class Model(models.Model):
default_permissions = ('add', 'change', 'delete', 'view', 'control')
abstract = True
depth = 1
many_depth = 0
@classonlymethod
def resolve_id(cls, id):
......
......@@ -258,8 +258,7 @@ class LDPSerializer(HyperlinkedModelSerializer):
nested_fields=Model.get_meta(model_class, 'nested_fields', []))
parent_depth = max(getattr(self.parent.Meta, "depth", 0) - 1, 0)
serializer_generator.depth = parent_depth
serializer_generator.many_depth = max(getattr(self.parent.Meta, "many_depth", 0) - 1, 0)
serializer = serializer_generator.build_serializer()(context=self.parent.context)
serializer = serializer_generator.build_read_serializer()(context=self.parent.context)
if parent_depth is 0:
serializer.Meta.fields = ["@id"]
return {'@id': '{}{}{}/'.format(settings.SITE_URL, '{}{}/', self.source),
......@@ -405,7 +404,7 @@ class LDPSerializer(HyperlinkedModelSerializer):
def many_init(cls, *args, **kwargs):
kwargs['child'] = cls(**kwargs)
try:
cls.Meta.depth = cls.compute_depth(kwargs['context']['view'].many_depth, cls.Meta.model, 'many_depth')
cls.Meta.depth = cls.compute_depth(kwargs['context']['view'].depth, cls.Meta.model, 'depth')
except KeyError:
pass
return ContainerSerializer(*args, **kwargs)
......
......@@ -63,7 +63,7 @@ failures = test_runner.run_tests([
'djangoldp.tests.tests_auto_author',
'djangoldp.tests.tests_get',
'djangoldp.tests.tests_delete',
# 'djangoldp.tests.tests_temp'
'djangoldp.tests.tests_temp'
])
if failures:
......
......@@ -18,3 +18,4 @@ class TestTemp(TestCase):
pass
......@@ -281,8 +281,8 @@ class Update(TestCase):
{
'@id': "_:b975",
'http://happy-dev.fr/owl/#description': "user description",
'http://happy-dev.fr/owl/#dummy': {
'@id' : './'
'http://happy-dev.fr/owl/#dummy': {
'@id': './'
}
},
{
......@@ -366,7 +366,8 @@ class Update(TestCase):
def test_missing_field_should_not_be_removed_with_fk_relation(self):
user = User.objects.create(username="alex", password="test")
peer = User.objects.create(username="sylvain", password="test2")
conversation = Conversation.objects.create(author_user=user, peer_user=peer, description="conversation description")
conversation = Conversation.objects.create(author_user=user, peer_user=peer,
description="conversation description")
body = [
{
'@id': "/conversations/{}/".format(conversation.pk),
......@@ -381,7 +382,8 @@ class Update(TestCase):
def test_empty_field_should_be_removed_with_fk_relation(self):
user = User.objects.create(username="alex", password="test")
peer = User.objects.create(username="sylvain", password="test2")
conversation = Conversation.objects.create(author_user=user, peer_user=peer, description="conversation description")
conversation = Conversation.objects.create(author_user=user, peer_user=peer,
description="conversation description")
body = [
{
'@id': "/conversations/{}/".format(conversation.pk),
......@@ -393,4 +395,3 @@ class Update(TestCase):
content_type='application/ld+json')
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['peer_user'], None)
......@@ -9,10 +9,13 @@ from django.shortcuts import get_object_or_404
from django.utils.decorators import classonlymethod
from guardian.shortcuts import get_objects_for_user
from pyld import jsonld
from rest_framework import status
from rest_framework.authentication import SessionAuthentication
from rest_framework.parsers import JSONParser
from rest_framework.renderers import JSONRenderer
from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
from djangoldp.models import LDPSource, Model
......@@ -90,8 +93,7 @@ class LDPViewSet(LDPViewSetGenerator):
"""An automatically generated viewset that serves models following the Linked Data Platform convention"""
fields = None
exclude = None
depth = 2
many_depth = 1
depth = 1
renderer_classes = (JSONLDRenderer,)
parser_classes = (JSONLDParser,)
authentication_classes = (NoCSRFAuthentication,)
......@@ -103,22 +105,69 @@ class LDPViewSet(LDPViewSetGenerator):
if hasattr(p, 'filter_class') and p.filter_class:
self.filter_backends = p.filter_class
self.serializer_class = self.build_serializer()
self.serializer_class = self.build_read_serializer()
self.write_serializer_class = self.build_write_serializer()
def build_serializer(self):
def build_read_serializer(self):
model_name = self.model._meta.object_name.lower()
lookup_field = get_resolver().reverse_dict[model_name + '-detail'][0][0][1][0]
meta_args = {'model': self.model, 'extra_kwargs': {
'@id': {'lookup_field': lookup_field}},
'depth': self.depth,
'extra_fields': self.nested_fields}
return self.build_serializer(meta_args, 'Read')
def build_write_serializer(self):
model_name = self.model._meta.object_name.lower()
lookup_field = get_resolver().reverse_dict[model_name + '-detail'][0][0][1][0]
meta_args = {'model': self.model, 'extra_kwargs': {
'@id': {'lookup_field': lookup_field}},
'depth': 10,
'extra_fields': self.nested_fields}
return self.build_serializer(meta_args, 'Write')
def build_serializer(self, meta_args, name_prefix):
if self.fields:
meta_args['fields'] = self.fields
else:
meta_args['exclude'] = self.exclude or ()
meta_class = type('Meta', (), meta_args)
from djangoldp.serializers import LDPSerializer
return type(LDPSerializer)(model_name + 'Serializer', (LDPSerializer,), {'Meta': meta_class})
return type(LDPSerializer)(self.model._meta.object_name.lower() + name_prefix + 'Serializer', (LDPSerializer,), {'Meta': meta_class})
def create(self, request, *args, **kwargs):
serializer = self.get_write_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def get_write_serializer(self, *args, **kwargs):
"""
Return the serializer instance that should be used for validating and
deserializing input, and for serializing output.
"""
serializer_class = self.get_write_serializer_class()
kwargs['context'] = self.get_serializer_context()
return serializer_class(*args, **kwargs)
def get_write_serializer_class(self):
"""
Return the class to use for the serializer.
Defaults to using `self.write_serializer_class`.
You may want to override this if you need to provide different
serializations depending on the incoming request.
(Eg. admins get full serialization, others get basic serialization)
"""
assert self.write_serializer_class is not None, (
"'%s' should either include a `write_serializer_class` attribute, "
"or override the `get_write_serializer_class()` method."
% self.__class__.__name__
)
return self.write_serializer_class
def perform_create(self, serializer, **kwargs):
if hasattr(self.model._meta, 'auto_author') and isinstance(self.request.user, get_user_model()):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment