Allowing the users to set an arbitrary number of items per page may
cause excessive load on the database. For example, a request to the
patch list has to compute the number of tags for each listed patch.

Signed-off-by: Franciszek Stachura <[email protected]>
---
I think that this limit should be implemented either way, but I added it
here mostly because the SQL query in generic_list now grows with
the number of items per page. This is a problem on MySQL as it by
default limits the query size to around 1MB. That technically should be
enough for at least 50k patches, but in my tests that was already too
much.
I believe that the API should be used for usecases that may justify
requesting a lot of patches.
---
 patchwork/models.py        | 5 +++++
 patchwork/paginator.py     | 2 +-
 patchwork/settings/base.py | 2 ++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/patchwork/models.py b/patchwork/models.py
index 4f2008c8..77ca6aaa 100644
--- a/patchwork/models.py
+++ b/patchwork/models.py
@@ -13,6 +13,7 @@ from django.conf import settings
 from django.contrib.auth.models import User
 from django.core.exceptions import ValidationError
 from django.core.validators import validate_unicode_slug
+from django.core.validators import MaxValueValidator
 from django.db import models
 from django.urls import reverse
 from django.utils.functional import cached_property
@@ -172,6 +173,7 @@ class UserProfile(models.Model):
         null=False,
         blank=False,
         help_text='Number of items to display per page',
+        validators=[MaxValueValidator(settings.MAX_ITEMS_PER_PAGE)],
     )
     show_ids = models.BooleanField(
         default=False,
@@ -208,6 +210,9 @@ class UserProfile(models.Model):
         except Token.DoesNotExist:
             return
 
+    def get_items_per_page(self):
+        return min(self.items_per_page, settings.MAX_ITEMS_PER_PAGE)
+
     def todo_patches(self, project=None):
         # filter on project, if necessary
         if project:
diff --git a/patchwork/paginator.py b/patchwork/paginator.py
index 6005f401..c79b493a 100644
--- a/patchwork/paginator.py
+++ b/patchwork/paginator.py
@@ -25,7 +25,7 @@ class Paginator(paginator.Paginator):
         items_per_page = settings.DEFAULT_ITEMS_PER_PAGE
 
         if request.user.is_authenticated:
-            items_per_page = request.user.profile.items_per_page
+            items_per_page = request.user.profile.get_items_per_page()
 
         super().__init__(objects, items_per_page)
 
diff --git a/patchwork/settings/base.py b/patchwork/settings/base.py
index 2b557fc1..d5dd82c4 100644
--- a/patchwork/settings/base.py
+++ b/patchwork/settings/base.py
@@ -266,6 +266,8 @@ ENABLE_REST_API = True
 REST_RESULTS_PER_PAGE = 30
 MAX_REST_RESULTS_PER_PAGE = 250
 
+MAX_ITEMS_PER_PAGE = 1000
+
 # Set to True to enable redirections or URLs from previous versions
 # of patchwork
 COMPAT_REDIR = True
-- 
2.55.0

_______________________________________________
Patchwork mailing list
[email protected]
https://lists.ozlabs.org/listinfo/patchwork

Reply via email to