Browse Source

fix #732: less hacky thread posts pagination implementation

Rafał Pitoń 8 years ago
parent
commit
7687c43e95

+ 8 - 0
misago/threads/paginator.py

@@ -9,6 +9,14 @@ class PostsPaginator(Paginator):
     Paginator that returns that makes last item on page
     repeat as first item on next page.
     """
+    def __init__(self, object_list, per_page, orphans=0,
+                 allow_empty_first_page=True):
+        per_page = int(per_page) - 1
+        if orphans:
+            orphans += 1
+        super(PostsPaginator, self).__init__(
+            object_list, per_page, orphans, allow_empty_first_page)
+
     def page(self, number):
         """
         Returns a Page object for the given 1-based page number.

+ 44 - 20
misago/threads/tests/test_paginator.py

@@ -10,46 +10,70 @@ class PostsPaginatorTests(TestCase):
 
         paginator = PostsPaginator(items, 5)
         self.assertEqual(self.get_paginator_items_list(paginator), [
-            [1, 2, 3, 4, 5, 6],
-            [6, 7, 8, 9, 10, 11],
-            [11, 12, 13, 14, 15, 16],
-            [16, 17, 18, 19, 20, 21],
-            [21, 22, 23, 24, 25, 26],
-            [26, 27, 28, 29, 30],
+            [1, 2, 3, 4, 5],
+            [5, 6, 7, 8, 9],
+            [9, 10, 11, 12, 13],
+            [13, 14, 15, 16, 17],
+            [17, 18, 19, 20, 21],
+            [21, 22, 23, 24, 25],
+            [25, 26, 27, 28, 29],
+            [29, 30],
         ])
 
     def test_paginator_orphans(self):
         """paginator handles orphans"""
-        items = [i + 1 for i in range(20)]
+        items = [i + 1 for i in range(16)]
 
         paginator = PostsPaginator(items, 8, 6)
         self.assertEqual(self.get_paginator_items_list(paginator), [
-            [1, 2, 3, 4, 5, 6, 7, 8, 9],
-            [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
+            [1, 2, 3, 4, 5, 6, 7, 8],
+            [8, 9, 10, 11, 12, 13, 14, 15, 16],
+        ])
+
+        paginator = PostsPaginator(items, 4, 4)
+        self.assertEqual(self.get_paginator_items_list(paginator), [
+            [1, 2, 3, 4],
+            [4, 5, 6, 7],
+            [7, 8, 9, 10],
+            [10, 11, 12, 13, 14, 15, 16],
+        ])
+
+        paginator = PostsPaginator(items, 5, 3)
+        self.assertEqual(self.get_paginator_items_list(paginator), [
+            [1, 2, 3, 4, 5],
+            [5, 6, 7, 8, 9],
+            [9, 10, 11, 12, 13, 14, 15, 16],
         ])
 
-        paginator = PostsPaginator(items, 8, 5)
-        self.assertEqual(paginator.num_pages, 2)
+        paginator = PostsPaginator(items, 6, 2)
         self.assertEqual(self.get_paginator_items_list(paginator), [
-            [1, 2, 3, 4, 5, 6, 7, 8, 9],
-            [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
+            [1, 2, 3, 4, 5, 6],
+            [6, 7, 8, 9, 10, 11],
+            [11, 12, 13, 14, 15, 16],
         ])
 
-        paginator = PostsPaginator(items, 9, 3)
-        self.assertEqual(paginator.num_pages, 2)
+        paginator = PostsPaginator(items, 7, 1)
         self.assertEqual(self.get_paginator_items_list(paginator), [
-            [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
-            [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
+            [1, 2, 3, 4, 5, 6, 7],
+            [7, 8, 9, 10, 11, 12, 13],
+            [13, 14, 15, 16],
         ])
 
+        paginator = PostsPaginator(items, 7, 3)
+        self.assertEqual(self.get_paginator_items_list(paginator), [
+            [1, 2, 3, 4, 5, 6, 7],
+            [7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
+        ])
+
+        paginator = PostsPaginator(items, 10, 6)
+        self.assertEqual(self.get_paginator_items_list(paginator), [items])
+
         # regression test for #732
         items = [i + 1 for i in range(24)]
 
         paginator = PostsPaginator(items, 18, 6)
         self.assertEqual(paginator.num_pages, 1)
-        self.assertEqual(self.get_paginator_items_list(paginator), [
-            [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24],
-        ])
+        self.assertEqual(self.get_paginator_items_list(paginator), [items])
 
         # extra tests for catching issues in excessively long datasets
         paginator = PostsPaginator([i + 1 for i in range(144)], 14, 6)

+ 8 - 5
misago/threads/viewmodels/posts.py

@@ -30,10 +30,6 @@ class ViewModel(object):
         posts = list(list_page.object_list)
         posters = []
 
-        next_page_post = None
-        if list_page.has_next():
-            next_page_post, posts = posts[-1], next_page_post[:-1]
-
         for post in posts:
             post.category = thread.category
             post.thread = thread_model
@@ -48,9 +44,16 @@ class ViewModel(object):
 
         # add events to posts
         if thread_model.has_events:
+            first_post = None
+            if list_page.has_previous():
+                first_post = posts[0]
+            last_post = None
+            if list_page.has_next():
+                last_post = posts[-1]
+
             events_limit = settings.MISAGO_EVENTS_PER_PAGE
             posts += self.get_events_queryset(
-                request, thread_model, events_limit, posts[0], next_page_post)
+                request, thread_model, events_limit, first_post, last_post)
 
             # sort both by pk
             posts.sort(key=lambda p: p.pk)