Skip to content
Snippets Groups Projects
Commit bb5a23f5 authored by Alexandre's avatar Alexandre
Browse files

Merge branch '148-filtered-fields' into 'master'

Resolve "Object of type 'Action' is not JSON serializable"

Closes #148

See merge request startinblox/djangoldp-packages/djangoldp!76
parents 3b4bb6cd b51fd3f6
No related branches found
No related tags found
1 merge request!76Resolve "Object of type 'Action' is not JSON serializable"
Pipeline #993 passed with stage
in 1 minute and 27 seconds
...@@ -5,10 +5,11 @@ from urllib import parse ...@@ -5,10 +5,11 @@ from urllib import parse
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.core.exceptions import ValidationError as DjangoValidationError from django.core.exceptions import ValidationError as DjangoValidationError
from django.core.urlresolvers import get_resolver, resolve, get_script_prefix, Resolver404 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.datastructures import MultiValueDictKeyError
from django.utils.encoding import uri_to_iri from django.utils.encoding import uri_to_iri
from rest_framework.exceptions import ValidationError 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.fields import get_error_detail, set_value
from rest_framework.relations import HyperlinkedRelatedField, ManyRelatedField, MANY_RELATION_KWARGS, Hyperlink 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
...@@ -237,6 +238,40 @@ class LDPSerializer(HyperlinkedModelSerializer): ...@@ -237,6 +238,40 @@ class LDPSerializer(HyperlinkedModelSerializer):
return super().build_field(field_name, info, model_class, nested_depth) 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): def build_standard_field(self, field_name, model_field):
class JSonLDStandardField: class JSonLDStandardField:
parent_view_name = None parent_view_name = None
......
from django.conf import settings from django.conf import settings
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.db import models from django.db import models
from django.utils.datetime_safe import date
from djangoldp.models import Model from djangoldp.models import Model
from djangoldp.permissions import AnonymousReadOnly from djangoldp.permissions import AnonymousReadOnly
...@@ -10,9 +11,13 @@ class Skill(Model): ...@@ -10,9 +11,13 @@ class Skill(Model):
title = models.CharField(max_length=255, blank=True, null=True) title = models.CharField(max_length=255, blank=True, null=True)
obligatoire = models.CharField(max_length=255) obligatoire = models.CharField(max_length=255)
slug = models.SlugField(blank=True, null=True, unique=True) 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: class Meta:
serializer_fields = ["@id", "title"] serializer_fields = ["@id", "title", "recent_jobs"]
lookup_field = 'slug' lookup_field = 'slug'
...@@ -20,9 +25,14 @@ class JobOffer(Model): ...@@ -20,9 +25,14 @@ class JobOffer(Model):
title = models.CharField(max_length=255, blank=True, null=True) title = models.CharField(max_length=255, blank=True, null=True)
skills = models.ManyToManyField(Skill, blank=True) skills = models.ManyToManyField(Skill, blank=True)
slug = models.SlugField(blank=True, null=True, unique=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: class Meta:
nested_fields = ["skills"] nested_fields = ["skills"]
serializer_fields = ["@id", "title", "skills", "recent_skills"]
container_path = "job-offers/" container_path = "job-offers/"
lookup_field = 'slug' lookup_field = 'slug'
......
...@@ -3,7 +3,7 @@ import json ...@@ -3,7 +3,7 @@ import json
from django.contrib.auth.models import User from django.contrib.auth.models import User
from rest_framework.test import APIRequestFactory, APIClient, APITestCase 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): class TestGET(APITestCase):
...@@ -40,3 +40,22 @@ class TestGET(APITestCase): ...@@ -40,3 +40,22 @@ class TestGET(APITestCase):
response = self.client.get('/posts/', content_type='application/ld+json') response = self.client.get('/posts/', content_type='application/ld+json')
self.assertEqual(response.status_code, 200) 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)
from django.contrib.auth.models import User
from django.test import TestCase from django.test import TestCase
from rest_framework.test import APIRequestFactory, APIClient from rest_framework.test import APIRequestFactory, APIClient
from rest_framework.utils import json
from djangoldp.serializers import LDPSerializer from djangoldp.tests.models import Skill, JobOffer
from djangoldp.tests.models import Post, UserProfile
from djangoldp.tests.models import Skill, JobOffer, Conversation, Message
class TestTemp(TestCase): class TestTemp(TestCase):
......
...@@ -15,7 +15,6 @@ from rest_framework.renderers import JSONRenderer ...@@ -15,7 +15,6 @@ from rest_framework.renderers import JSONRenderer
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from djangoldp.models import LDPSource, Model from djangoldp.models import LDPSource, Model
from .serializers import LDPSerializer
class JSONLDRenderer(JSONRenderer): class JSONLDRenderer(JSONRenderer):
...@@ -118,6 +117,7 @@ class LDPViewSet(LDPViewSetGenerator): ...@@ -118,6 +117,7 @@ class LDPViewSet(LDPViewSetGenerator):
else: else:
meta_args['exclude'] = self.exclude or () meta_args['exclude'] = self.exclude or ()
meta_class = type('Meta', (), meta_args) meta_class = type('Meta', (), meta_args)
from djangoldp.serializers import LDPSerializer
return type(LDPSerializer)(model_name + 'Serializer', (LDPSerializer,), {'Meta': meta_class}) return type(LDPSerializer)(model_name + 'Serializer', (LDPSerializer,), {'Meta': meta_class})
def perform_create(self, serializer, **kwargs): def perform_create(self, serializer, **kwargs):
...@@ -196,6 +196,7 @@ class LDPNestedViewSet(LDPViewSet): ...@@ -196,6 +196,7 @@ class LDPNestedViewSet(LDPViewSet):
nested_related_name = related_field.remote_field.name nested_related_name = related_field.remote_field.name
return cls.urls( return cls.urls(
lookup_field= Model.get_meta(related_field.related_model, 'lookup_field', 'pk'),
model=related_field.related_model, model=related_field.related_model,
exclude=(nested_related_name,) if related_field.one_to_many else (), exclude=(nested_related_name,) if related_field.one_to_many else (),
parent_model=cls.get_model(**kwargs), parent_model=cls.get_model(**kwargs),
......
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