From b51fd3f6a00e21e02d6e626c2cd4a665ac3d9c7e Mon Sep 17 00:00:00 2001 From: Jean-Baptiste <bleme@pm.me> Date: Thu, 4 Jul 2019 19:20:53 +0200 Subject: [PATCH] update: serialize object method --- djangoldp/serializers.py | 37 ++++++++++++++++++++++++++++++++++- djangoldp/tests/models.py | 12 +++++++++++- djangoldp/tests/tests_get.py | 21 +++++++++++++++++++- djangoldp/tests/tests_temp.py | 6 +----- djangoldp/views.py | 3 ++- 5 files changed, 70 insertions(+), 9 deletions(-) diff --git a/djangoldp/serializers.py b/djangoldp/serializers.py index 4e37dec9..b0450646 100644 --- a/djangoldp/serializers.py +++ b/djangoldp/serializers.py @@ -5,10 +5,11 @@ from urllib import parse from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ValidationError as DjangoValidationError from django.core.urlresolvers import get_resolver, resolve, get_script_prefix, Resolver404 +from django.db.models import QuerySet from django.utils.datastructures import MultiValueDictKeyError from django.utils.encoding import uri_to_iri from rest_framework.exceptions import ValidationError -from rest_framework.fields import SkipField, empty +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 @@ -237,6 +238,40 @@ class LDPSerializer(HyperlinkedModelSerializer): return super().build_field(field_name, info, model_class, nested_depth) + def build_property_field(self, field_name, model_class): + class JSonLDPropertyField(ReadOnlyField): + def to_representation(self, instance): + if isinstance(instance, QuerySet): + data = list(instance) + model_class = instance.model + from djangoldp.views import LDPViewSet + + serializer_generator = LDPViewSet(model=model_class, + lookup_field=Model.get_meta(model_class, 'lookup_field', 'pk'), + permission_classes=Model.get_meta(model_class, 'permission_classes', []), + fields=Model.get_meta(model_class, 'serializer_fields', []), + 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) + if parent_depth is 0: + serializer.Meta.fields=["@id"] + return {'@id': '', + '@type': 'ldp:Container', + 'ldp:contains': [serializer.to_representation(item) if item is not None else None for item + in data], + 'permissions': Model.get_permissions(self.parent.Meta.model, self.context['request'].user, + ['view', 'add']) + } + else: + return instance + + field_class = JSonLDPropertyField + field_kwargs = {} + + return field_class, field_kwargs + def build_standard_field(self, field_name, model_field): class JSonLDStandardField: parent_view_name = None diff --git a/djangoldp/tests/models.py b/djangoldp/tests/models.py index b23632ae..d0d16a23 100644 --- a/djangoldp/tests/models.py +++ b/djangoldp/tests/models.py @@ -1,6 +1,7 @@ from django.conf import settings from django.contrib.auth import get_user_model from django.db import models +from django.utils.datetime_safe import date from djangoldp.models import Model from djangoldp.permissions import AnonymousReadOnly @@ -10,9 +11,13 @@ class Skill(Model): title = models.CharField(max_length=255, blank=True, null=True) obligatoire = models.CharField(max_length=255) slug = models.SlugField(blank=True, null=True, unique=True) + date = models.DateTimeField(auto_now_add=True, blank=True) + + def recent_jobs(self): + return self.joboffer_set.filter(date__gte=date.today()) class Meta: - serializer_fields = ["@id", "title"] + serializer_fields = ["@id", "title", "recent_jobs"] lookup_field = 'slug' @@ -20,9 +25,14 @@ class JobOffer(Model): title = models.CharField(max_length=255, blank=True, null=True) skills = models.ManyToManyField(Skill, blank=True) slug = models.SlugField(blank=True, null=True, unique=True) + date = models.DateTimeField(auto_now_add=True, blank=True) + + def recent_skills(self): + return self.skills.filter(date__gte=date.today()) class Meta: nested_fields = ["skills"] + serializer_fields = ["@id", "title", "skills", "recent_skills"] container_path = "job-offers/" lookup_field = 'slug' diff --git a/djangoldp/tests/tests_get.py b/djangoldp/tests/tests_get.py index 9f5564d9..21c4b71e 100644 --- a/djangoldp/tests/tests_get.py +++ b/djangoldp/tests/tests_get.py @@ -3,7 +3,7 @@ import json from django.contrib.auth.models import User from rest_framework.test import APIRequestFactory, APIClient, APITestCase -from djangoldp.tests.models import Post, Task, Invoice +from djangoldp.tests.models import Post, Task, Invoice, JobOffer, Skill class TestGET(APITestCase): @@ -40,3 +40,22 @@ class TestGET(APITestCase): response = self.client.get('/posts/', content_type='application/ld+json') self.assertEqual(response.status_code, 200) + def test_get_filtered_fields(self): + skill = Skill.objects.create(title="Java", obligatoire="ok", slug="1") + skill2 = Skill.objects.create(title="Java", obligatoire="ok", slug="2") + job = JobOffer.objects.create(title="job", slug="1") + job.skills.add(skill) + job.skills.add(skill2) + job.save() + response = self.client.get('/job-offers/{}/'.format(job.slug), content_type='application/ld+json') + self.assertEqual(response.status_code, 200) + self.assertIn('recent_skills', response.data) + + def test_get_reverse_filtered_fields(self): + skill = Skill.objects.create(title="Java", obligatoire="ok", slug="1") + job = JobOffer.objects.create(title="job", slug="1") + job.skills.add(skill) + job.save() + response = self.client.get('/skills/{}/'.format(skill.slug), content_type='application/ld+json') + self.assertEqual(response.status_code, 200) + self.assertIn('recent_jobs', response.data) diff --git a/djangoldp/tests/tests_temp.py b/djangoldp/tests/tests_temp.py index 8a4b4d0f..578eb8a3 100644 --- a/djangoldp/tests/tests_temp.py +++ b/djangoldp/tests/tests_temp.py @@ -1,11 +1,7 @@ -from django.contrib.auth.models import User from django.test import TestCase from rest_framework.test import APIRequestFactory, APIClient -from rest_framework.utils import json -from djangoldp.serializers import LDPSerializer -from djangoldp.tests.models import Post, UserProfile -from djangoldp.tests.models import Skill, JobOffer, Conversation, Message +from djangoldp.tests.models import Skill, JobOffer class TestTemp(TestCase): diff --git a/djangoldp/views.py b/djangoldp/views.py index 3d2b48b9..b20cd12c 100644 --- a/djangoldp/views.py +++ b/djangoldp/views.py @@ -15,7 +15,6 @@ from rest_framework.renderers import JSONRenderer from rest_framework.viewsets import ModelViewSet from djangoldp.models import LDPSource, Model -from .serializers import LDPSerializer class JSONLDRenderer(JSONRenderer): @@ -118,6 +117,7 @@ class LDPViewSet(LDPViewSetGenerator): 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}) def perform_create(self, serializer, **kwargs): @@ -196,6 +196,7 @@ class LDPNestedViewSet(LDPViewSet): nested_related_name = related_field.remote_field.name return cls.urls( + lookup_field= Model.get_meta(related_field.related_model, 'lookup_field', 'pk'), model=related_field.related_model, exclude=(nested_related_name,) if related_field.one_to_many else (), parent_model=cls.get_model(**kwargs), -- GitLab