1
1
from copy import copy
2
2
from inspect import getargspec
3
+
4
+ import django
5
+
3
6
from django import template
4
7
from django .template .loader import get_template
5
8
from django .utils .safestring import mark_safe
6
9
from django .contrib .admin .templatetags .admin_list import result_list
7
10
from django .contrib .admin .views .main import ALL_VAR , PAGE_VAR
8
11
from django .utils .html import escape
12
+ from django .utils .html import format_html
9
13
from suit .compat import tpl_context_class
10
14
15
+ # Starting with Django 3.2, the pagination is 1-based instead of 0-based.
16
+ # I've taken the implementations (latest at the time of release 3.2) from https://github.com/django/django/blob/main/django/contrib/admin/templatetags/admin_list.py
17
+ # to use in the implementations below. Older versions of django will use the old implementation and will keep working.
18
+ # There are corresponding CSS changes in suit/static/suit/less/ui/pagination.less to fix the pagination, as the code below generates different html objects.
19
+ USE_NEW_DJANGO_ADMIN_PAGINATION = django .get_version () >= '3.2'
20
+
11
21
try :
12
22
# Python 3.
13
23
from urllib .parse import parse_qs
24
34
25
35
register = template .Library ()
26
36
37
+
27
38
DOT = '.'
28
39
29
40
30
41
@register .simple_tag
31
42
def paginator_number (cl , i ):
32
43
"""
33
- Generates an individual page index link in a paginated list.
44
+ Generate an individual page index link in a paginated list.
34
45
"""
35
- if i == DOT :
36
- return mark_safe (
37
- '<li class="disabled"><a href="#" onclick="return false;">..'
38
- '.</a></li>' )
46
+ if not USE_NEW_DJANGO_ADMIN_PAGINATION :
47
+ if i == DOT :
48
+ return mark_safe (
49
+ '<li class="disabled"><a href="#" onclick="return false;">..'
50
+ '.</a></li>' )
51
+ elif i == cl .page_num :
52
+ return mark_safe (
53
+ '<li class="active"><a href="">%d</a></li> ' % (i + 1 ))
54
+ else :
55
+ return mark_safe ('<li><a href="%s"%s>%d</a></li> ' % (
56
+ escape (cl .get_query_string ({PAGE_VAR : i })),
57
+ (i == cl .paginator .num_pages - 1 and ' class="end"' or '' ),
58
+ i + 1 ))
59
+
60
+ if i == cl .paginator .ELLIPSIS :
61
+ return format_html ('<span class="disabled">{}</span> ' , cl .paginator .ELLIPSIS )
39
62
elif i == cl .page_num :
40
- return mark_safe (
41
- '<li class="active"><a href="">%d</a></li> ' % (i + 1 ))
63
+ return format_html ('<span class="this-page">{}</span> ' , i )
42
64
else :
43
- return mark_safe ('<li><a href="%s"%s>%d</a></li> ' % (
44
- escape (cl .get_query_string ({PAGE_VAR : i })),
45
- (i == cl .paginator .num_pages - 1 and ' class="end"' or '' ),
46
- i + 1 ))
65
+ return format_html (
66
+ '<a href="{}"{}>{}</a> ' ,
67
+ cl .get_query_string ({PAGE_VAR : i }),
68
+ mark_safe (' class="end"' if i == cl .paginator .num_pages else '' ),
69
+ i ,
70
+ )
47
71
48
72
49
73
@register .simple_tag
50
74
def paginator_info (cl ):
75
+ if not USE_NEW_DJANGO_ADMIN_PAGINATION :
76
+ paginator = cl .paginator
77
+
78
+ # If we show all rows of list (without pagination)
79
+ if cl .show_all and cl .can_show_all :
80
+ entries_from = 1 if paginator .count > 0 else 0
81
+ entries_to = paginator .count
82
+ else :
83
+ entries_from = (
84
+ (paginator .per_page * cl .page_num ) + 1 ) if paginator .count > 0 else 0
85
+ entries_to = entries_from - 1 + paginator .per_page
86
+ if paginator .count < entries_to :
87
+ entries_to = paginator .count
88
+
89
+ return '%s - %s' % (entries_from , entries_to )
90
+
51
91
paginator = cl .paginator
52
92
53
93
# If we show all rows of list (without pagination)
54
94
if cl .show_all and cl .can_show_all :
55
95
entries_from = 1 if paginator .count > 0 else 0
56
96
entries_to = paginator .count
57
97
else :
58
- entries_from = (
59
- (paginator .per_page * cl .page_num ) + 1 ) if paginator .count > 0 else 0
98
+ entries_from = ((paginator .per_page * (cl .page_num - 1 )) + 1 ) if paginator .count > 0 else 0
60
99
entries_to = entries_from - 1 + paginator .per_page
61
100
if paginator .count < entries_to :
62
101
entries_to = paginator .count
@@ -67,48 +106,61 @@ def paginator_info(cl):
67
106
@register .inclusion_tag ('admin/pagination.html' )
68
107
def pagination (cl ):
69
108
"""
70
- Generates the series of links to the pages in a paginated list.
109
+ Generate the series of links to the pages in a paginated list.
71
110
"""
72
- paginator , page_num = cl .paginator , cl .page_num
111
+ if not USE_NEW_DJANGO_ADMIN_PAGINATION :
112
+ paginator , page_num = cl .paginator , cl .page_num
73
113
74
- pagination_required = (not cl .show_all or not cl .can_show_all ) \
75
- and cl .multi_page
76
- if not pagination_required :
77
- page_range = []
78
- else :
79
- ON_EACH_SIDE = 3
80
- ON_ENDS = 2
81
-
82
- # If there are 10 or fewer pages, display links to every page.
83
- # Otherwise, do some fancy
84
- if paginator .num_pages <= 8 :
85
- page_range = range (paginator .num_pages )
86
- else :
87
- # Insert "smart" pagination links, so that there are always ON_ENDS
88
- # links at either end of the list of pages, and there are always
89
- # ON_EACH_SIDE links at either end of the "current page" link.
114
+ pagination_required = (not cl .show_all or not cl .can_show_all ) \
115
+ and cl .multi_page
116
+ if not pagination_required :
90
117
page_range = []
91
- if page_num > (ON_EACH_SIDE + ON_ENDS ):
92
- page_range .extend (range (0 , ON_EACH_SIDE - 1 ))
93
- page_range .append (DOT )
94
- page_range .extend (range (page_num - ON_EACH_SIDE , page_num + 1 ))
95
- else :
96
- page_range .extend (range (0 , page_num + 1 ))
97
- if page_num < (paginator .num_pages - ON_EACH_SIDE - ON_ENDS - 1 ):
98
- page_range .extend (
99
- range (page_num + 1 , page_num + ON_EACH_SIDE + 1 ))
100
- page_range .append (DOT )
101
- page_range .extend (
102
- range (paginator .num_pages - ON_ENDS , paginator .num_pages ))
103
- else :
104
- page_range .extend (range (page_num + 1 , paginator .num_pages ))
118
+ else :
119
+ ON_EACH_SIDE = 3
120
+ ON_ENDS = 2
105
121
122
+ # If there are 10 or fewer pages, display links to every page.
123
+ # Otherwise, do some fancy
124
+ if paginator .num_pages <= 8 :
125
+ page_range = range (paginator .num_pages )
126
+ else :
127
+ # Insert "smart" pagination links, so that there are always ON_ENDS
128
+ # links at either end of the list of pages, and there are always
129
+ # ON_EACH_SIDE links at either end of the "current page" link.
130
+ page_range = []
131
+ if page_num > (ON_EACH_SIDE + ON_ENDS ):
132
+ page_range .extend (range (0 , ON_EACH_SIDE - 1 ))
133
+ page_range .append (DOT )
134
+ page_range .extend (range (page_num - ON_EACH_SIDE , page_num + 1 ))
135
+ else :
136
+ page_range .extend (range (0 , page_num + 1 ))
137
+ if page_num < (paginator .num_pages - ON_EACH_SIDE - ON_ENDS - 1 ):
138
+ page_range .extend (
139
+ range (page_num + 1 , page_num + ON_EACH_SIDE + 1 ))
140
+ page_range .append (DOT )
141
+ page_range .extend (
142
+ range (paginator .num_pages - ON_ENDS , paginator .num_pages ))
143
+ else :
144
+ page_range .extend (range (page_num + 1 , paginator .num_pages ))
145
+
146
+ need_show_all_link = cl .can_show_all and not cl .show_all and cl .multi_page
147
+ return {
148
+ 'cl' : cl ,
149
+ 'pagination_required' : pagination_required ,
150
+ 'show_all_url' : need_show_all_link and cl .get_query_string (
151
+ {ALL_VAR : '' }),
152
+ 'page_range' : page_range ,
153
+ 'ALL_VAR' : ALL_VAR ,
154
+ '1' : 1 ,
155
+ }
156
+
157
+ pagination_required = (not cl .show_all or not cl .can_show_all ) and cl .multi_page
158
+ page_range = cl .paginator .get_elided_page_range (cl .page_num ) if pagination_required else []
106
159
need_show_all_link = cl .can_show_all and not cl .show_all and cl .multi_page
107
160
return {
108
161
'cl' : cl ,
109
162
'pagination_required' : pagination_required ,
110
- 'show_all_url' : need_show_all_link and cl .get_query_string (
111
- {ALL_VAR : '' }),
163
+ 'show_all_url' : need_show_all_link and cl .get_query_string ({ALL_VAR : '' }),
112
164
'page_range' : page_range ,
113
165
'ALL_VAR' : ALL_VAR ,
114
166
'1' : 1 ,
0 commit comments