From 6fcdf28d086227ecf4960f36c672013b646d06f2 Mon Sep 17 00:00:00 2001 From: David Davis Date: Mon, 18 Sep 2023 10:13:13 -0400 Subject: [PATCH] Handle empty list for href and id in filter Fix bug where empty list for the pulp_href__in or pulp_id__in filters return all results instead of no results. The problem is that when using FilterMethod, django-filter just simply ignores None and empty set and returns the full list of results: https://github.com/carltongibson/django-filter/blob/e4a70a667a0bf3882fd44b557bc76583d2c65cd1/django_filters/filters.py#L804-L805 There's no way to update the method to prevent this since this logic happens before the method is called. Instead, this change moves the method to the filter and adds a None check. fixes #4437 --- CHANGES/4437.bugfix | 2 ++ pulpcore/filters.py | 19 +++++++++++-------- pulpcore/tests/functional/api/test_filter.py | 4 ++++ 3 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 CHANGES/4437.bugfix diff --git a/CHANGES/4437.bugfix b/CHANGES/4437.bugfix new file mode 100644 index 00000000000..aa86cf89c21 --- /dev/null +++ b/CHANGES/4437.bugfix @@ -0,0 +1,2 @@ +Fixed bug where supplying an empty list for ``pulp_href__in`` or ``pulp_id__in`` would return all +results instead of none. diff --git a/pulpcore/filters.py b/pulpcore/filters.py index 46bd6e1bf99..9f263fe3cef 100644 --- a/pulpcore/filters.py +++ b/pulpcore/filters.py @@ -124,11 +124,19 @@ def filter(self, qs, value): class IdInFilter(BaseInFilter, filters.UUIDFilter): - pass + def filter(self, qs, value): + if value is None: + return qs + return qs.filter(pk__in=value) class HREFInFilter(BaseInFilter, filters.CharFilter): - pass + def filter(self, qs, value): + if value is None: + return qs + + pks = [extract_pk(href) for href in value] + return qs.filter(pk__in=pks) class PulpTypeFilter(filters.ChoiceFilter): @@ -271,7 +279,7 @@ class BaseFilterSet(filterset.FilterSet): help_text = {} pulp_id__in = IdInFilter(field_name="pk", lookup_expr="in") - pulp_href__in = HREFInFilter(field_name="pk", method="filter_pulp_href") + pulp_href__in = HREFInFilter(field_name="pk") q = ExpressionFilter() FILTER_DEFAULTS = { @@ -307,11 +315,6 @@ class BaseFilterSet(filterset.FilterSet): "ne": _("not equal to"), } - def filter_pulp_href(self, queryset, name, value): - # Convert each href to a pk - pks = [extract_pk(href) for href in value] - return queryset.filter(pk__in=pks) - @classmethod def get_filters(cls): filters = super().get_filters() diff --git a/pulpcore/tests/functional/api/test_filter.py b/pulpcore/tests/functional/api/test_filter.py index 891e77b6a44..cca95958550 100644 --- a/pulpcore/tests/functional/api/test_filter.py +++ b/pulpcore/tests/functional/api/test_filter.py @@ -87,6 +87,10 @@ def test_pulp_id_href_filter( redi_results = redirect_contentguard_api_client.list(**{filter: rbac_sample}) assert redi_results.count == 0 + # test out empty list + redi_results = redirect_contentguard_api_client.list(**{filter: []}) + assert redi_results.count == 0 + # Test that filter fails when not a valid type with pytest.raises(ApiException) as exc: content_guards_api_client.list(**{filter: ["hello"]})