Просмотр исходного кода

Basic implementation for cursor based pagination on threads list

rafalp 6 лет назад
Родитель
Сommit
a31b11cfb7
2 измененных файлов с 16 добавлено и 12 удалено
  1. 9 5
      misago/core/cursorpaginator.py
  2. 7 7
      misago/threads/viewmodels/threads.py

+ 9 - 5
misago/core/cursorpaginator.py

@@ -7,32 +7,36 @@ class CursorPaginator:
         self.order_by = order_by
         self.per_page = int(per_page)
 
-    def get_page(self, start=0):
+    def get(self, start=0):
         if start < 0:
             raise InvalidPage()
 
-        object_list = self._get_slice(start)
+        object_list = list(self._get_slice(start))
         if start and not object_list:
             raise EmptyPage()
 
         next_cursor = None
         if len(object_list) > self.per_page:
             next_slice_first_item = object_list.pop(-1)
-            next_cursor = getattr(next_slice_first_item, self.order_by)
+            attr_name = self.order_by.lstrip("-")
+            next_cursor = getattr(next_slice_first_item, attr_name)
 
         return Page(start, object_list, next_cursor)
 
     def _get_slice(self, start):
         page_len = self.per_page + 1
         if start:
-            filter_name = "%s__gte" % self.order_by
+            if self.order_by.startswith("-"):
+                filter_name = "%s__lte" % self.order_by[1:]
+            else:
+                filter_name = "%s__gte" % self.order_by
             return self.queryset.filter(**{filter_name: start})[:page_len]
         return self.queryset[:page_len]
 
 
 class Page:
     def __init__(self, start, object_list, next_):
-        self.start = start or None
+        self.start = start or 0
         self.object_list = object_list
         self.next = next_
 

+ 7 - 7
misago/threads/viewmodels/threads.py

@@ -6,6 +6,7 @@ from django.utils.translation import gettext_lazy
 
 from ...acl.objectacl import add_acl_to_obj
 from ...conf import settings
+from ...core.cursorpaginator import CursorPaginator
 from ...core.shortcuts import paginate, pagination_dict
 from ...readtracker import threadstracker
 from ...readtracker.dates import get_cutoff_date
@@ -59,15 +60,14 @@ class ViewModel:
             base_queryset, category_model, threads_categories
         )
 
-        list_page = paginate(
+        paginator = CursorPaginator(
             threads_queryset,
-            page,
-            settings.MISAGO_THREADS_PER_PAGE,
-            settings.MISAGO_THREADS_TAIL,
+            "-last_post_id",
+            settings.MISAGO_THREADS_PER_PAGE
         )
-        paginator = pagination_dict(list_page)
+        list_page = paginator.get(0)
 
-        if list_page.number > 1:
+        if list_page.start:
             threads = list(list_page.object_list)
         else:
             pinned_threads = list(
@@ -136,7 +136,7 @@ class ViewModel:
             }
         }
 
-        context["THREADS"].update(self.paginator)
+        #context["THREADS"].update(self.paginator)
         return context
 
     def get_template_context(self):