From 6ff2022508b596c7078fd059a9188db7b3d76f18 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste <bleme@pm.me> Date: Wed, 20 Feb 2019 16:46:40 +0100 Subject: [PATCH] bugfix: remove list element must not delete data on db --- djangoldp/serializers.py | 21 +++++-- djangoldp/tests/tests_update.py | 99 +++++++++++++++++---------------- 2 files changed, 65 insertions(+), 55 deletions(-) diff --git a/djangoldp/serializers.py b/djangoldp/serializers.py index 18a63a1d..54c599c6 100644 --- a/djangoldp/serializers.py +++ b/djangoldp/serializers.py @@ -27,6 +27,8 @@ class LDListMixin: pass if isinstance(data, dict): data = [data] + if isinstance(data, str) and str.startswith("http"): + data = [{'@id': data}] return [self.child.to_internal_value(item) for item in data] def to_representation(self, value): @@ -336,6 +338,7 @@ class LDPSerializer(HyperlinkedModelSerializer): else: value = self.internal_create(validated_data=value, model=manager._meta.model) setattr(instance, attr, value) + instance.save() self.save_or_update_nested_list(instance, nested_fields) @@ -344,12 +347,17 @@ class LDPSerializer(HyperlinkedModelSerializer): def save_or_update_nested_list(self, instance, nested_fields): for (field_name, data) in nested_fields: - try: - getattr(instance, field_name).clear() - except AttributeError: - pass + manager = getattr(instance, field_name) + + item_pk_to_keep = list(map(lambda e: int(e['pk']), filter(lambda x: 'pk' in x, data))) + for item in list(manager.all()): + if not item.pk in item_pk_to_keep: + if getattr(manager, 'through', None) is None: + item.delete() + else: + manager.remove(item) + for item in data: - manager = getattr(instance, field_name) if 'pk' in item: oldObj = manager.model.objects.get(pk=item['pk']) savedItem = self.update(instance=oldObj, validated_data=item) @@ -363,4 +371,5 @@ class LDPSerializer(HyperlinkedModelSerializer): pass savedItem = self.internal_create(validated_data=item, model=manager.model) - getattr(instance, field_name).add(savedItem) + if getattr(manager, 'through', None) is not None and manager.through._meta.auto_created: + manager.add(savedItem) diff --git a/djangoldp/tests/tests_update.py b/djangoldp/tests/tests_update.py index 622b55ef..39083e20 100644 --- a/djangoldp/tests/tests_update.py +++ b/djangoldp/tests/tests_update.py @@ -89,60 +89,61 @@ class Update(TestCase): self.assertEquals(skills[1].title, "skill1") # no change self.assertEquals(skills[2].title, "skill2 UP") # title updated - def test_update_graph_2(self): - skill = Skill.objects.create(title="to drop", obligatoire="obligatoire") - skill1 = Skill.objects.create(title="skill1", obligatoire="obligatoire") - skill2 = Skill.objects.create(title="skill2", obligatoire="obligatoire") - job1 = JobOffer.objects.create(title="job test") - job1.skills.add(skill) - - job = {"@graph": - [ - { - "@id": "https://happy-dev.fr/job-offers/{}/".format(job1.pk), - "title": "job test updated", - "skills": { - "@id": "https://happy-dev.fr/job-offers/{}/skills/".format(job1.pk) - } - }, - { - "@id": "_.123", - "title": "new skill", - "obligatoire": "okay" - }, - { - "@id": "https://happy-dev.fr/skills/{}/".format(skill1.pk), - }, - { - "@id": "https://happy-dev.fr/skills/{}/".format(skill2.pk), - "title": "skill2 UP" - }, - { - '@id': "https://happy-dev.fr/job-offers/{}/skills/".format(job1.pk), - "ldp:contains": [ - {"@id": "https://happy-dev.fr/skills/{}/".format(skill1.pk)}, - {"@id": "https://happy-dev.fr/skills/{}/".format(skill2.pk)}, - {"@id": "_.123"}, - ] + def test_update_graph_2(self): + skill = Skill.objects.create(title="to drop", obligatoire="obligatoire") + skill1 = Skill.objects.create(title="skill1", obligatoire="obligatoire") + skill2 = Skill.objects.create(title="skill2", obligatoire="obligatoire") + job1 = JobOffer.objects.create(title="job test") + job1.skills.add(skill) + + job = {"@graph": + [ + { + "@id": "https://happy-dev.fr/job-offers/{}/".format(job1.pk), + "title": "job test updated", + "skills": { + "@id": "https://happy-dev.fr/job-offers/{}/skills/".format(job1.pk) } - ] - } + }, + { + "@id": "_.123", + "title": "new skill", + "obligatoire": "okay" + }, + { + "@id": "https://happy-dev.fr/skills/{}/".format(skill1.pk), + }, + { + "@id": "https://happy-dev.fr/skills/{}/".format(skill2.pk), + "title": "skill2 UP" + }, + { + '@id': "https://happy-dev.fr/job-offers/{}/skills/".format(job1.pk), + "ldp:contains": [ + {"@id": "https://happy-dev.fr/skills/{}/".format(skill1.pk)}, + {"@id": "https://happy-dev.fr/skills/{}/".format(skill2.pk)}, + {"@id": "_.123"}, + ] + } + ] + } - meta_args = {'model': JobOffer, 'depth': 1, 'fields': ("@id", "title", "skills")} + 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, instance=job1) - serializer.is_valid() - result = serializer.save() + meta_class = type('Meta', (), meta_args) + serializer_class = type(LDPSerializer)('JobOfferSerializer', (LDPSerializer,), {'Meta': meta_class}) + serializer = serializer_class(data=job, instance=job1) + serializer.is_valid() + result = serializer.save() - skills = result.skills.all().order_by('title') + skills = result.skills.all().order_by('title') - self.assertEquals(result.title, "job test updated") - self.assertIs(result.skills.count(), 3) - self.assertEquals(skills[0].title, "new skill") # new skill - self.assertEquals(skills[1].title, "skill1") # no change - self.assertEquals(skills[2].title, "skill2 UP") # title updated + self.assertEquals(result.title, "job test updated") + self.assertIs(result.skills.count(), 3) + self.assertEquals(skills[0].title, "new skill") # new skill + self.assertEquals(skills[1].title, "skill1") # no change + self.assertEquals(skills[2].title, "skill2 UP") # title updated + self.assertEquals(skill, skill._meta.model.objects.get(pk=skill.pk)) # title updated def test_update_list_with_reverse_relation(self): user1 = User.objects.create() -- GitLab