From b9d645642129c38064d65e8c0d6f0606cc9bb06c Mon Sep 17 00:00:00 2001 From: Jean-Baptiste <bleme@pm.me> Date: Fri, 22 Feb 2019 10:58:29 +0100 Subject: [PATCH 1/2] update: Try to reproduce the error by completing a unit test case --- djangoldp/tests/tests_save.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/djangoldp/tests/tests_save.py b/djangoldp/tests/tests_save.py index 7e05496a..557e0070 100644 --- a/djangoldp/tests/tests_save.py +++ b/djangoldp/tests/tests_save.py @@ -15,6 +15,7 @@ class Save(TestCase): "ldp:contains": [ {"@id": "https://happy-dev.fr/skills/{}/".format(skill1.pk)}, {"@id": "https://happy-dev.fr/skills/{}/".format(skill2.pk), "title": "skill2 UP"}, + {"title": "skill3 NEW", "obligatoire":"obligatoire"}, ]} } @@ -27,9 +28,10 @@ class Save(TestCase): result = serializer.save() self.assertEquals(result.title, "job test") - self.assertIs(result.skills.count(), 2) + self.assertIs(result.skills.count(), 3) self.assertEquals(result.skills.all()[0].title, "skill1") # no change self.assertEquals(result.skills.all()[1].title, "skill2 UP") # title updated + self.assertEquals(result.skills.all()[2].title, "skill3 NEW") # creation on the fly def test_save_without_nested_fields(self): skill1 = Skill.objects.create(title="skill1", obligatoire="obligatoire") -- GitLab From 4bb15727308bc66b404b415bc7c268ac7f0fbe48 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste <bleme@pm.me> Date: Sun, 24 Feb 2019 19:16:58 +0100 Subject: [PATCH 2/2] update: fix issue #90 --- djangoldp/serializers.py | 19 ++++++++++++++++++- djangoldp/tests/tests_save.py | 22 ++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/djangoldp/serializers.py b/djangoldp/serializers.py index 54c599c6..9bb033b6 100644 --- a/djangoldp/serializers.py +++ b/djangoldp/serializers.py @@ -13,6 +13,7 @@ from rest_framework.fields import get_error_detail, set_value from rest_framework.relations import HyperlinkedRelatedField, ManyRelatedField, MANY_RELATION_KWARGS from rest_framework.serializers import HyperlinkedModelSerializer, ListSerializer 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 from rest_framework.utils.serializer_helpers import ReturnDict @@ -309,7 +310,23 @@ class LDPSerializer(HyperlinkedModelSerializer): return super().get_value(dictionary) def create(self, validated_data): - return self.internal_create(validated_data, model=self.Meta.model) + instance = self.internal_create(validated_data, model=self.Meta.model) + + self.attach_related_object(instance, validated_data) + + return instance + + def attach_related_object(self, instance, validated_data): + ModelClass = self.Meta.model + + info = model_meta.get_field_info(ModelClass) + many_to_many = {} + for field_name, relation_info in info.relations.items(): + if relation_info.to_many and relation_info.reverse and not (field_name in validated_data): + rel = getattr(instance._meta.model, field_name).rel + if rel.name in validated_data: + related = validated_data[rel.name] + getattr(instance, field_name).add(related) def internal_create(self, validated_data, model): nested_fields = [] diff --git a/djangoldp/tests/tests_save.py b/djangoldp/tests/tests_save.py index 557e0070..4cf4f0d4 100644 --- a/djangoldp/tests/tests_save.py +++ b/djangoldp/tests/tests_save.py @@ -49,3 +49,25 @@ class Save(TestCase): self.assertEquals(result.title, "job test") self.assertIs(result.skills.count(), 0) + def test_save_on_sub_iri(self): + """ + POST /job-offers/1/skills/ + """ + job = JobOffer.objects.create(title="job test") + skill = {"title": "new SKILL"} + + meta_args = {'model': Skill, 'depth': 1, 'fields': ("@id", "title")} + + meta_class = type('Meta', (), meta_args) + serializer_class = type(LDPSerializer)('SkillSerializer', (LDPSerializer,), {'Meta': meta_class}) + serializer = serializer_class(data=skill) + serializer.is_valid() + kwargs = {} + kwargs['joboffer'] = job + result = serializer.save(**kwargs) + + self.assertEquals(result.title, "new SKILL") + self.assertIs(result.joboffer_set.count(), 1) + self.assertEquals(result.joboffer_set.get(), job) + self.assertIs(result.joboffer_set.get().skills.count(), 1) + -- GitLab