Skip to content

Commit 2d24d80

Browse files
author
yangxg
committed
Merge branch 'Step20_complete-pagination'
2 parents cbd321a + 69a4cdf commit 2d24d80

File tree

2 files changed

+167
-14
lines changed

2 files changed

+167
-14
lines changed

blog/views.py

Lines changed: 132 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,138 @@ class IndexView(ListView):
3030
model = Post
3131
template_name = 'blog/index.html'
3232
context_object_name = 'post_list'
33-
paginate_by = 10
33+
paginate_by = 1
34+
35+
def get_context_data(self, **kwargs):
36+
"""
37+
在视图函数中将模板变量传递给模板是通过给 render 函数的 context 参数传递一个字典实现的,
38+
例如 render(request, 'blog/index.html', context={'post_list': post_list}),
39+
这里传递了一个 {'post_list': post_list} 字典给模板。
40+
在类视图中,这个需要传递的模板变量字典是通过 get_context_data 获得的,
41+
所以我们复写该方法,以便我们能够自己再插入一些我们自定义的模板变量进去。
42+
"""
43+
44+
# 首先获得父类生成的传递给模板的字典。
45+
context = super().get_context_data(**kwargs)
46+
47+
# 父类生成的字典中已有 paginator、page_obj、is_paginated 这三个模板变量,
48+
# paginator 是 Paginator 的一个实例,
49+
# page_obj 是 Page 的一个实例,
50+
# is_paginated 是一个布尔变量,用于指示是否已分页。
51+
# 例如如果规定每页 10 个数据,而本身只有 5 个数据,其实就用不着分页,此时 is_paginated=False。
52+
# 关于什么是 Paginator,Page 类在 Django Pagination 简单分页:http://zmrenwu.com/post/34/ 中已有详细说明。
53+
# 由于 context 是一个字典,所以调用 get 方法从中取出某个键对应的值。
54+
paginator = context.get('paginator')
55+
page = context.get('page_obj')
56+
is_paginated = context.get('is_paginated')
57+
58+
# 调用自己写的 pagination_data 方法获得显示分页导航条需要的数据,见下方。
59+
pagination_data = self.pagination_data(paginator, page, is_paginated)
60+
61+
# 将分页导航条的模板变量更新到 context 中,注意 pagination_data 方法返回的也是一个字典。
62+
context.update(pagination_data)
63+
64+
# 将更新后的 context 返回,以便 ListView 使用这个字典中的模板变量去渲染模板。
65+
# 注意此时 context 字典中已有了显示分页导航条所需的数据。
66+
return context
67+
68+
def pagination_data(self, paginator, page, is_paginated):
69+
if not is_paginated:
70+
# 如果没有分页,则无需显示分页导航条,不用任何分页导航条的数据,因此返回一个空的字典
71+
return {}
72+
73+
# 当前页左边连续的页码号,初始值为空
74+
left = []
75+
76+
# 当前页右边连续的页码号,初始值为空
77+
right = []
78+
79+
# 标示第 1 页页码后是否需要显示省略号
80+
left_has_more = False
81+
82+
# 标示最后一页页码前是否需要显示省略号
83+
right_has_more = False
84+
85+
# 标示是否需要显示第 1 页的页码号。
86+
# 因为如果当前页左边的连续页码号中已经含有第 1 页的页码号,此时就无需再显示第 1 页的页码号,
87+
# 其它情况下第一页的页码是始终需要显示的。
88+
# 初始值为 False
89+
first = False
90+
91+
# 标示是否需要显示最后一页的页码号。
92+
# 需要此指示变量的理由和上面相同。
93+
last = False
94+
95+
# 获得用户当前请求的页码号
96+
page_number = page.number
97+
98+
# 获得分页后的总页数
99+
total_pages = paginator.num_pages
100+
101+
# 获得整个分页页码列表,比如分了四页,那么就是 [1, 2, 3, 4]
102+
page_range = paginator.page_range
103+
104+
if page_number == 1:
105+
# 如果用户请求的是第一页的数据,那么当前页左边的不需要数据,因此 left=[](已默认为空)。
106+
# 此时只要获取当前页右边的连续页码号,
107+
# 比如分页页码列表是 [1, 2, 3, 4],那么获取的就是 right = [2, 3]。
108+
# 注意这里只获取了当前页码后连续两个页码,你可以更改这个数字以获取更多页码。
109+
right = page_range[page_number:page_number + 2]
110+
111+
# 如果最右边的页码号比最后一页的页码号减去 1 还要小,
112+
# 说明最右边的页码号和最后一页的页码号之间还有其它页码,因此需要显示省略号,通过 right_has_more 来指示。
113+
if right[-1] < total_pages - 1:
114+
right_has_more = True
115+
116+
# 如果最右边的页码号比最后一页的页码号小,说明当前页右边的连续页码号中不包含最后一页的页码
117+
# 所以需要显示最后一页的页码号,通过 last 来指示
118+
if right[-1] < total_pages:
119+
last = True
120+
121+
elif page_number == total_pages:
122+
# 如果用户请求的是最后一页的数据,那么当前页右边就不需要数据,因此 right=[](已默认为空),
123+
# 此时只要获取当前页左边的连续页码号。
124+
# 比如分页页码列表是 [1, 2, 3, 4],那么获取的就是 left = [2, 3]
125+
# 这里只获取了当前页码后连续两个页码,你可以更改这个数字以获取更多页码。
126+
left = page_range[(page_number - 3) if (page_number - 3) > 0 else 0:page_number - 1]
127+
128+
# 如果最左边的页码号比第 2 页页码号还大,
129+
# 说明最左边的页码号和第 1 页的页码号之间还有其它页码,因此需要显示省略号,通过 left_has_more 来指示。
130+
if left[0] > 2:
131+
left_has_more = True
132+
133+
# 如果最左边的页码号比第 1 页的页码号大,说明当前页左边的连续页码号中不包含第一页的页码,
134+
# 所以需要显示第一页的页码号,通过 first 来指示
135+
if left[0] > 1:
136+
first = True
137+
else:
138+
# 用户请求的既不是最后一页,也不是第 1 页,则需要获取当前页左右两边的连续页码号,
139+
# 这里只获取了当前页码前后连续两个页码,你可以更改这个数字以获取更多页码。
140+
left = page_range[(page_number - 3) if (page_number - 3) > 0 else 0:page_number - 1]
141+
right = page_range[page_number:page_number + 2]
142+
143+
# 是否需要显示最后一页和最后一页前的省略号
144+
if right[-1] < total_pages - 1:
145+
right_has_more = True
146+
if right[-1] < total_pages:
147+
last = True
148+
149+
# 是否需要显示第 1 页和第 1 页后的省略号
150+
if left[0] > 2:
151+
left_has_more = True
152+
if left[0] > 1:
153+
first = True
154+
155+
data = {
156+
'left': left,
157+
'right': right,
158+
'left_has_more': left_has_more,
159+
'right_has_more': right_has_more,
160+
'first': first,
161+
'last': last,
162+
}
163+
164+
return data
34165

35166

36167
"""

templates/blog/index.html

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ <h1 class="entry-title">
2929
<div class="no-post">暂时还没有发布的文章!</div>
3030
{% endfor %}
3131

32+
{% comment %}
33+
简单分页导航:
3234
{% if is_paginated %}
3335
<div class="pagination-simple">
3436
<!-- 如果当前页还有上一页,显示一个上一页的按钮 -->
@@ -43,18 +45,38 @@ <h1 class="entry-title">
4345
{% endif %}
4446
</div>
4547
{% endif %}
48+
{% endcomment %}
4649

47-
<div class="pagination">
48-
<ul>
49-
<li><a href="">1</a></li>
50-
<li><a href="">...</a></li>
51-
<li><a href="">4</a></li>
52-
<li><a href="">5</a></li>
53-
<li class="current"><a href="">6</a></li>
54-
<li><a href="">7</a></li>
55-
<li><a href="">8</a></li>
56-
<li><a href="">...</a></li>
57-
<li><a href="">11</a></li>
58-
</ul>
59-
</div>
50+
{% comment %}
51+
完善的分页导航
52+
{% endcomment %}
53+
{% if is_paginated %}
54+
<div class="pagination">
55+
<ul>
56+
{% if first %}
57+
<li><a href="?page=1">1</a></li>
58+
{% endif %}
59+
{% if left %}
60+
{% if left_has_more %}
61+
<li><span>...</span></li>
62+
{% endif %}
63+
{% for i in left %}
64+
<li><a href="?page={{ i }}">{{ i }}</a></li>
65+
{% endfor %}
66+
{% endif %}
67+
<li class="current"><a href="?page={{ page_obj.number }}">{{ page_obj.number }}</a></li>
68+
{% if right %}
69+
{% for i in right %}
70+
<li><a href="?page={{ i }}">{{ i }}</a></li>
71+
{% endfor %}
72+
{% if right_has_more %}
73+
<li><span>...</span></li>
74+
{% endif %}
75+
{% endif %}
76+
{% if last %}
77+
<li><a href="?page={{ paginator.num_pages }}">{{ paginator.num_pages }}</a></li>
78+
{% endif %}
79+
</ul>
80+
</div>
81+
{% endif %}
6082
{% endblock main %}

0 commit comments

Comments
 (0)