diff --git a/component_catalog/filters.py b/component_catalog/filters.py index ecfa5f7e..5e08ae09 100644 --- a/component_catalog/filters.py +++ b/component_catalog/filters.py @@ -205,6 +205,13 @@ class PackageFilterSet(DataspacedFilterSet): "sha1", "md5", ], + ordering=[ + "type", + "namespace", + "name", + # In a search context, we want to display the most recent versions first + "-version", + ], search_fields=[ "type", "namespace", diff --git a/component_catalog/tests/test_filters.py b/component_catalog/tests/test_filters.py index 1b2764ac..82827d65 100644 --- a/component_catalog/tests/test_filters.py +++ b/component_catalog/tests/test_filters.py @@ -377,8 +377,8 @@ def test_package_filterset_search_match_order_on_purl_fields(self): data = {"q": "django"} filterset = PackageFilterSet(dataspace=self.dataspace, data=data) - expected = ["pkg:pypi/django@4.0", "pkg:pypi/django@5.0"] - self.assertEqual(sorted(expected), self.sorted_results(filterset.qs)) + expected = ["pkg:pypi/django@5.0", "pkg:pypi/django@4.0"] + self.assertEqual([str(package) for package in filterset.qs], expected) def test_package_filterset_is_vulnerable_filter(self): package1 = make_package(self.dataspace, is_vulnerable=True) diff --git a/dje/filters.py b/dje/filters.py index e9b1dffb..ff8d1f2d 100644 --- a/dje/filters.py +++ b/dje/filters.py @@ -230,9 +230,10 @@ class MatchOrderedSearchFilter(SearchRankFilter): https://www.postgresql.org/docs/10/static/functions-matching.html#POSIX-CONSTRAINT-ESCAPES-TABLE """ - def __init__(self, match_order_fields, *args, **kwargs): + def __init__(self, match_order_fields, ordering=None, *args, **kwargs): super().__init__(*args, **kwargs) self.match_order_fields = match_order_fields + self.ordering = ordering def get_match_order_lookups(self, lookup_type, value): or_queries = [ @@ -258,12 +259,13 @@ def filter(self, qs, value): output_field=IntegerField(), ) - default_ordering = self.model._meta.ordering + ordering = self.ordering or self.model._meta.ordering simple_search_qs = ( qs.filter(self.get_match_order_lookups("icontains", value)) .annotate(match_order=match_order) - .order_by("match_order", *default_ordering) + # Sort by match pertiance first, then by field values + .order_by("match_order", *ordering) ) if simple_search_qs.exists():