From 5707dae09276f795eece45dffd7900ee88170dac Mon Sep 17 00:00:00 2001 From: tdruez <489057+tdruez@users.noreply.github.com> Date: Tue, 14 Mar 2023 20:07:00 -0100 Subject: [PATCH] Do not include the pagination in the filter query string #563 (#635) * Do not include the pagination in the filter query string #563 Signed-off-by: Thomas Druez --------- Signed-off-by: Thomas Druez --- CHANGELOG.rst | 4 ++++ docs/scancodeio-settings.rst | 8 ++++++++ scancodeio/settings.py | 13 +++++++++++++ scanpipe/filters.py | 4 ++++ scanpipe/tests/test_views.py | 19 +++++++++++++++++++ scanpipe/views.py | 10 +++++----- 6 files changed, 53 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a0f52a6c2..d73ade164 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -31,6 +31,10 @@ v33.0.0 (unreleased) with current Project/CodebaseResource path scheme. https://github.com/nexB/scancode.io/pull/624 +- Add ``SCANCODEIO_PAGINATE_BY`` setting to customize the number of items displayed per + page for each object type. + https://github.com/nexB/scancode.io/issues/563 + v32.0.1 (2023-02-20) -------------------- diff --git a/docs/scancodeio-settings.rst b/docs/scancodeio-settings.rst index 521cc2598..ee905829f 100644 --- a/docs/scancodeio-settings.rst +++ b/docs/scancodeio-settings.rst @@ -171,6 +171,14 @@ A valid policies file is required to enable compliance-related features. Check out the :ref:`tutorial_license_policies` tutorial for in-depth coverage of this feature. +SCANCODEIO_PAGINATE_BY +---------------------- + +The number of objects display per page for each object type can be customized with the +following setting:: + + SCANCODEIO_PAGINATE_BY=project=30,error=50,resource=100,package=100,dependency=100 + SCANCODEIO_REST_API_PAGE_SIZE ----------------------------- diff --git a/scancodeio/settings.py b/scancodeio/settings.py index 9fe0fabac..7bf01ab0e 100644 --- a/scancodeio/settings.py +++ b/scancodeio/settings.py @@ -76,6 +76,19 @@ # Default to 24 hours. SCANCODEIO_TASK_TIMEOUT = env.int("SCANCODEIO_TASK_TIMEOUT", default=86400) +# List views pagination, controls the number of items displayed per page. +# Syntax in .env: SCANCODEIO_PAGINATE_BY=project=10,project_error=10 +SCANCODEIO_PAGINATE_BY = env.dict( + "SCANCODEIO_PAGINATE_BY", + default={ + "project": 20, + "error": 50, + "resource": 100, + "package": 100, + "dependency": 100, + }, +) + # Default limit for "most common" entries in QuerySets. SCANCODEIO_MOST_COMMON_LIMIT = env.int("SCANCODEIO_MOST_COMMON_LIMIT", default=7) diff --git a/scanpipe/filters.py b/scanpipe/filters.py index ce2fb720b..77831c3f9 100644 --- a/scanpipe/filters.py +++ b/scanpipe/filters.py @@ -149,6 +149,9 @@ def render_option(self, name, selected_choices, option_value, option_label): data[name] = option_value selected = data == self.data or option_value in selected_choices + # Do not include the pagination in the filter query string. + data.pop(PAGE_VAR, None) + css_class = str(self.extra_css_class) if selected: css_class += " is-active" @@ -224,6 +227,7 @@ class ProjectFilterSet(FilterSetUtilsMixin, django_filters.FilterSet): class Meta: model = Project fields = ["is_archived"] + exclude = ["page"] def __init__(self, data=None, *args, **kwargs): """ diff --git a/scanpipe/tests/test_views.py b/scanpipe/tests/test_views.py index 4abbe8dd7..37b4d979e 100644 --- a/scanpipe/tests/test_views.py +++ b/scanpipe/tests/test_views.py @@ -123,6 +123,25 @@ def test_scanpipe_views_project_list_state_of_filters_in_search_form(self): expected = '' self.assertContains(response, expected, html=True) + @mock.patch("scanpipe.views.ProjectListView.get_paginate_by") + def test_scanpipe_views_project_list_filters_exclude_page(self, mock_paginate_by): + url = reverse("project_list") + # Create another project to enable pagination + Project.objects.create(name="project2") + mock_paginate_by.return_value = 1 + + data = {"page": "2"} + response = self.client.get(url, data=data) + + expected = 'Name' + self.assertContains(response, expected) + expected = '
  • All
  • ' + self.assertContains(response, expected) + expected = 'All' + self.assertContains(response, expected) + expected = 'Newest' + self.assertContains(response, expected) + def test_scanpipe_views_project_details_is_archived(self): url = self.project1.get_absolute_url() expected1 = "WARNING: This project is archived and read-only." diff --git a/scanpipe/views.py b/scanpipe/views.py index f3bf5d3aa..55b94a52c 100644 --- a/scanpipe/views.py +++ b/scanpipe/views.py @@ -401,7 +401,7 @@ class ProjectListView( filterset_class = ProjectFilterSet template_name = "scanpipe/project_list.html" prefetch_related = ["runs"] - paginate_by = 20 + paginate_by = settings.SCANCODEIO_PAGINATE_BY.get("project", 20) table_columns = [ "name", { @@ -847,7 +847,7 @@ class CodebaseResourceListView( model = CodebaseResource filterset_class = ResourceFilterSet template_name = "scanpipe/resource_list.html" - paginate_by = 100 + paginate_by = settings.SCANCODEIO_PAGINATE_BY.get("resource", 100) prefetch_related = ["discovered_packages"] table_columns = [ "path", @@ -884,7 +884,7 @@ class DiscoveredPackageListView( model = DiscoveredPackage filterset_class = PackageFilterSet template_name = "scanpipe/package_list.html" - paginate_by = 100 + paginate_by = settings.SCANCODEIO_PAGINATE_BY.get("package", 100) prefetch_related = ["codebase_resources"] table_columns = [ "package_url", @@ -906,7 +906,7 @@ class DiscoveredDependencyListView( model = DiscoveredDependency filterset_class = DependencyFilterSet template_name = "scanpipe/dependency_list.html" - paginate_by = 100 + paginate_by = settings.SCANCODEIO_PAGINATE_BY.get("dependency", 100) prefetch_related = ["for_package", "datafile_resource"] table_columns = [ "package_url", @@ -932,7 +932,7 @@ class ProjectErrorListView( model = ProjectError filterset_class = ErrorFilterSet template_name = "scanpipe/error_list.html" - paginate_by = 50 + paginate_by = settings.SCANCODEIO_PAGINATE_BY.get("error", 50) table_columns = [ "model", "message",