Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fixes #11102] Faceting: prefiltering #11205

Merged
merged 1 commit into from
Jun 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions geonode/base/api/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,16 @@ class TKeywordsFilter(BaseFilterBackend):
"""

def filter_queryset(self, request, queryset, view):
return (
self.filter_queryset_GROUP(request, queryset, view)
if "force_and" not in request.GET
else self.filter_queryset_AND(request, queryset, view)
)
# we must make the GET mutable since in the filters, some queryparams are popped
request.GET._mutable = True
try:
return (
self.filter_queryset_GROUP(request, queryset, view)
if "force_and" not in request.GET
else self.filter_queryset_AND(request, queryset, view)
)
finally:
request.GET._mutable = False

def filter_queryset_AND(self, request, queryset, view):
"""
Expand Down
23 changes: 23 additions & 0 deletions geonode/facets/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
from django.urls import reverse

from geonode.base.models import Thesaurus, ThesaurusLabel, ThesaurusKeyword, ThesaurusKeywordLabel, ResourceBase, Region
from geonode.facets.models import facet_registry
from geonode.facets.providers.region import RegionFacetProvider

Check warning on line 32 in geonode/facets/tests.py

View check run for this annotation

Codecov / codecov/patch

geonode/facets/tests.py#L31-L32

Added lines #L31 - L32 were not covered by tests
from geonode.tests.base import GeoNodeBaseTestSupport
import geonode.facets.views as views

Expand Down Expand Up @@ -294,6 +296,27 @@
obj = json.loads(res.content)
self.assertEqual(exp, len(obj["topics"]["items"]), f"Unexpected topic count {exp} for facet {facet}")

def test_prefiltering(self):
reginfo = RegionFacetProvider().get_info()
t0info = facet_registry.get_provider("t_0").get_info()
t1info = facet_registry.get_provider("t_1").get_info()

Check warning on line 302 in geonode/facets/tests.py

View check run for this annotation

Codecov / codecov/patch

geonode/facets/tests.py#L299-L302

Added lines #L299 - L302 were not covered by tests

for facet, filters, totals, count0 in (
("t_0", {}, 2, 10),
("t_0", {reginfo["key"]: "R0"}, 1, 1),
("t_1", {}, 2, 10),
("t_1", {reginfo["key"]: "R0"}, 1, 2),
("t_1", {reginfo["key"]: "R1"}, 2, 3),
(reginfo["name"], {}, 2, 4),
(reginfo["name"], {t0info["key"]: self.thesauri_k["0_0"].id}, 2, 1),
(reginfo["name"], {t1info["key"]: self.thesauri_k["1_0"].id}, 2, 3),
):
req = self.rf.get(reverse("get_facet", args=[facet]), data=filters)
res: JsonResponse = views.get_facet(req, facet)
obj = json.loads(res.content)
self.assertEqual(totals, obj["topics"]["total"], f"Bad totals for facet '{facet} and filter {filters}")
self.assertEqual(count0, obj["topics"]["items"][0]["count"], f"Bad count0 for facet '{facet}")

Check warning on line 318 in geonode/facets/tests.py

View check run for this annotation

Codecov / codecov/patch

geonode/facets/tests.py#L314-L318

Added lines #L314 - L318 were not covered by tests

def test_user_auth(self):
# make sure the user authorization pre-filters the visible resources
# TODO test
Expand Down
13 changes: 11 additions & 2 deletions geonode/facets/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
from django.urls import reverse

from django.conf import settings

from geonode.base.api.views import ResourceBaseViewSet
from geonode.base.models import ResourceBase
from geonode.facets.models import FacetProvider, DEFAULT_FACET_PAGE_SIZE, facet_registry
from geonode.security.utils import get_visible_resources
Expand Down Expand Up @@ -160,8 +162,15 @@
:return: a QuerySet on ResourceBase
"""
logger.debug("Filtering by user '%s'", request.user)
# return ResourceBase.objects
return get_visible_resources(ResourceBase.objects, request.user)
filters = {k: vlist for k, vlist in request.query_params.lists() if k.startswith("filter{")}

if filters:
viewset = ResourceBaseViewSet(request=request, format_kwarg={}, kwargs=filters)
viewset.initial(request)
return get_visible_resources(queryset=viewset.filter_queryset(viewset.get_queryset()), user=request.user)

Check warning on line 170 in geonode/facets/views.py

View check run for this annotation

Codecov / codecov/patch

geonode/facets/views.py#L168-L170

Added lines #L168 - L170 were not covered by tests
else:
# return ResourceBase.objects
return get_visible_resources(ResourceBase.objects, request.user)

Check warning on line 173 in geonode/facets/views.py

View check run for this annotation

Codecov / codecov/patch

geonode/facets/views.py#L173

Added line #L173 was not covered by tests


def _resolve_language(request) -> (str, bool):
Expand Down
Loading