@@ -30,7 +30,138 @@ class IndexView(ListView):
30
30
model = Post
31
31
template_name = 'blog/index.html'
32
32
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
34
165
35
166
36
167
"""
0 commit comments