From ad157916ddc9dc48882d0128066d5c22e30f1d57 Mon Sep 17 00:00:00 2001 From: Chatewgne Date: Mon, 13 Jan 2025 11:27:19 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20[BUG]=20Prevent=20objects=20from?= =?UTF-8?q?=20being=20returned=20several=20times=20in=20APIv2=20by=20filte?= =?UTF-8?q?ring=20on=20ManyToMany=20(refs=20#4448)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/changelog.rst | 4 ++++ geotrek/api/tests/test_v2.py | 7 +++++++ geotrek/api/v2/filters.py | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 19b737c071..e070277305 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -15,6 +15,10 @@ CHANGELOG - Move Treks' accessibility pictures into the attached files tab (refs #2967) - Removes the display of an object's structure in its properties tab title +**Bug fixes** + +- Prevent objects from being returned several times in APIv2 by filtering on ManyToMany (#4448) + **Documentation** - Update theme color diff --git a/geotrek/api/tests/test_v2.py b/geotrek/api/tests/test_v2.py index 40f5f35cea..9cd6fa9f51 100644 --- a/geotrek/api/tests/test_v2.py +++ b/geotrek/api/tests/test_v2.py @@ -1031,6 +1031,13 @@ def test_trek_theme_filter(self): json_response = response.json() self.assertEqual(len(json_response.get('results')), 0) + # Test result is not duplicated + self.parent.themes.add(self.theme3) + response = self.get_trek_list({'themes': f"{self.theme2.pk},{self.theme3.pk}"}) + self.assertEqual(response.status_code, 200) + json_response = response.json() + self.assertEqual(len(json_response.get('results')), 1) + def test_trek_portal_filter(self): response = self.get_trek_list({'portals': self.portal.pk}) # test response code diff --git a/geotrek/api/v2/filters.py b/geotrek/api/v2/filters.py index 0d30fba837..d227e81148 100644 --- a/geotrek/api/v2/filters.py +++ b/geotrek/api/v2/filters.py @@ -743,7 +743,7 @@ def filter_queryset(self, request, queryset, view): Q(name__icontains=q) | Q(description__icontains=q) | Q(description_teaser__icontains=q) | Q(ambiance__icontains=q) ) - return qs + return qs.distinct() def get_schema_fields(self, view): return (