Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • djangoldp-packages/djangoldp
  • decentral1se/djangoldp
  • femmefaytale/djangoldp
  • jvtrudel/djangoldp
4 results
Show changes
Commits on Source (11)
import json
from django.core.exceptions import ImproperlyConfigured
from django.core.urlresolvers import get_resolver
from django.utils.datastructures import MultiValueDictKeyError
from guardian.shortcuts import get_perms
from rest_framework.fields import empty
from rest_framework.relations import HyperlinkedRelatedField, ManyRelatedField, MANY_RELATION_KWARGS
from rest_framework.serializers import HyperlinkedModelSerializer, ListSerializer
from rest_framework.utils.serializer_helpers import ReturnDict
from rest_framework.utils.field_mapping import get_nested_relation_kwargs
from guardian.shortcuts import get_perms
from rest_framework.utils.serializer_helpers import ReturnDict
class LDListMixin:
def to_internal_value(self, data):
data = json.loads(data)
# data = json.loads(data)
try:
data = data['ldp:contains']
except TypeError:
pass
if isinstance(data, dict):
data = [data]
return [self.child_relation.to_internal_value(item['@id']) for item in data]
return [self.child.to_internal_value(item) for item in data]
def to_representation(self, value):
return {'@id': self.id, 'ldp:contains': super().to_representation(value)}
def get_attribute(self, instance):
parent_id_field = self.parent.fields[self.parent.url_field_name]
context = self.parent.context
parent_id = parent_id_field.get_url(instance, parent_id_field.view_name, context['request'], context['format'])
self.id = parent_id + self.field_name+"/"
self.id = parent_id + self.field_name + "/"
return super().get_attribute(instance)
class ContainerSerializer(LDListMixin, ListSerializer):
id=''
id = ''
@property
def data(self):
return ReturnDict(super(ListSerializer, self).data, serializer=self)
def create(self, validated_data):
return super().create(validated_data)
def to_internal_value(self, data):
try:
return super().to_internal_value(data['@id'])
except:
return super().to_internal_value(data)
class ManyJsonLdRelatedField(LDListMixin, ManyRelatedField):
pass
class JsonLdField(HyperlinkedRelatedField):
def __init__(self, view_name=None, **kwargs):
super().__init__(view_name, **kwargs)
self.get_lookup_args()
def get_lookup_args(self):
try:
lookup_field = get_resolver().reverse_dict[self.view_name][0][0][1][0]
......@@ -45,19 +65,20 @@ class JsonLdField(HyperlinkedRelatedField):
except MultiValueDictKeyError:
pass
class JsonLdRelatedField(JsonLdField):
def to_representation(self, value):
try:
return {'@id': super().to_representation(value)}
except ImproperlyConfigured:
return value.pk
def to_internal_value(self, data):
try:
return super().to_internal_value(data['@id'])
except:
return super().to_internal_value(data)
@classmethod
def many_init(cls, *args, **kwargs):
list_kwargs = {'child_relation': cls(*args, **kwargs)}
......@@ -66,36 +87,52 @@ class JsonLdRelatedField(JsonLdField):
list_kwargs[key] = kwargs[key]
return ManyJsonLdRelatedField(**list_kwargs)
class JsonLdIdentityField(JsonLdField):
def __init__(self, view_name=None, **kwargs):
kwargs['read_only'] = True
kwargs['source'] = '*'
super().__init__(view_name, **kwargs)
def use_pk_only_optimization(self):
return False
def to_internal_value(self, data):
try:
return super().to_internal_value(data['@id'])
except:
return super().to_internal_value(data)
class LDPSerializer(HyperlinkedModelSerializer):
url_field_name = "@id"
serializer_related_field = JsonLdRelatedField
serializer_url_field = JsonLdIdentityField
def get_default_field_names(self, declared_fields, model_info):
try:
fields = list(self.Meta.model._meta.serializer_fields)
except:
except AttributeError:
fields = super().get_default_field_names(declared_fields, model_info)
try:
fields.remove(self.Meta.model._meta.auto_author)
except ValueError:
pass
except AttributeError:
pass
return fields + list(getattr(self.Meta, 'extra_fields', []))
def to_representation(self, obj):
data = super().to_representation(obj)
if hasattr(obj._meta, 'rdf_type'):
data['@type'] = obj._meta.rdf_type
data['permissions'] = [{'mode': {'@type': name.split('_')[0]}} for name in get_perms(self.context['request'].user, obj)]
data['permissions'] = [{'mode': {'@type': name.split('_')[0]}} for name in
get_perms(self.context['request'].user, obj)]
return data
def build_nested_field(self, field_name, relation_info, nested_depth):
class NestedLDPSerializer(self.__class__):
class Meta:
model = relation_info.related_model
depth = nested_depth - 1
......@@ -104,10 +141,32 @@ class LDPSerializer(HyperlinkedModelSerializer):
except AttributeError:
fields = '__all__'
return NestedLDPSerializer, get_nested_relation_kwargs(relation_info)
def to_internal_value(self, data):
model = self.Meta.model
return self.serializer_related_field(
view_name='{}-detail'.format(model._meta.object_name.lower()),
queryset=model.objects.all()).to_internal_value(data)
kwargs = get_nested_relation_kwargs(relation_info)
kwargs['read_only'] = False
kwargs['required'] = False
return NestedLDPSerializer, kwargs
@classmethod
def many_init(cls, *args, **kwargs):
kwargs['child'] = cls()
return ContainerSerializer(*args, **kwargs)
def create(self, validated_data):
nested_fields = []
nested_fields_name = list(filter(lambda key: isinstance(validated_data[key], list), validated_data))
for field_name in nested_fields_name:
nested_fields.append((field_name, validated_data.pop(field_name)))
obj = self.Meta.model.objects.create(**validated_data)
for (field_name, data) in nested_fields:
for item in data:
getattr(obj, field_name).add(item)
return obj
from django.test import TestCase
# Create your tests here.
from django.conf import settings
from django.db import models
class Skill(models.Model):
title = models.CharField(max_length=255, blank=True, null=True)
class JobOffer(models.Model):
title = models.CharField(max_length=255, blank=True, null=True)
skills = models.ManyToManyField(Skill, blank=True)
import django
import sys
from django.conf import settings
settings.configure(DEBUG=True,
DATABASES={
'default': {
'ENGINE': 'django.db.backends.sqlite3',
}
},
ROOT_URLCONF='djangoldp.tests.urls',
INSTALLED_APPS=('django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.admin',
'guardian',
'djangoldp',
'djangoldp.tests',
))
django.setup()
from django.test.runner import DiscoverRunner
test_runner = DiscoverRunner(verbosity=1)
failures = test_runner.run_tests(['djangoldp.tests.tests'])
if failures:
sys.exit(failures)
from django.test import TestCase
from djangoldp.serializers import LDPSerializer
from djangoldp.tests.models import Skill, JobOffer
class Serializer(TestCase):
def test_container_serializer_save(self):
skill1 = Skill.objects.create(title="skill1")
skill2 = Skill.objects.create(title="skill2")
job = {"title": "job test",
"skills": {
"ldp:contains": [
{"@id": "https://happy-dev.fr/skills/{}/".format(skill1.pk)},
{"@id": "https://happy-dev.fr/skills/{}/".format(skill2.pk)},
]}
}
meta_args = {'model': JobOffer, 'depth': 1, 'fields': ("@id", "title", "skills")}
meta_class = type('Meta', (), meta_args)
serializer_class = type(LDPSerializer)('JobOfferSerializer', (LDPSerializer,), {'Meta': meta_class})
serializer = serializer_class(data=job)
serializer.is_valid()
result = serializer.save()
self.assertEquals(result.title, "job test")
self.assertIs(result.skills.count(), 2)
def test_save_without_nested_fields(self):
skill1 = Skill.objects.create(title="skill1")
skill2 = Skill.objects.create(title="skill2")
job = {"title": "job test"}
meta_args = {'model': JobOffer, 'depth': 1, 'fields': ("@id", "title", "skills")}
meta_class = type('Meta', (), meta_args)
serializer_class = type(LDPSerializer)('JobOfferSerializer', (LDPSerializer,), {'Meta': meta_class})
serializer = serializer_class(data=job)
serializer.is_valid()
result = serializer.save()
self.assertEquals(result.title, "job test")
self.assertIs(result.skills.count(), 0)
from djangoldp.tests.models import Skill, JobOffer
from djangoldp.views import LDPViewSet
from django.conf.urls import url
urlpatterns = [
url(r'^skills/', LDPViewSet.urls(model=Skill, permission_classes=[], fields=["@id", "title"], nested_fields=[])),
url(r'^job-offers/', LDPViewSet.urls(model=JobOffer, nested_fields=["skills"], permission_classes=())),
]
\ No newline at end of file
......@@ -130,6 +130,10 @@ class LDPViewSet(LDPViewSetGenerator):
response["Accept-Post"] = "application/ld+json"
return response
def update(self, request, *args, **kwargs):
response = super().update(request, *args, **kwargs)
return response
class LDPNestedViewSet(LDPViewSet):
"""A special case of LDPViewSet serving objects of a relation of a given object (e.g. members of a group, or skills of a user)"""
parent_model = None
......