@@ -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"""
0 commit comments