设置后的效果如下:
- Django 给我们提供了分页的功能:`Paginator`和`Page`类都是用来做分页的。他们在Django中的路径为:`from django.core.paginator import Page, Paginator`
- 先简单解释一下他们的属性和方法:
-
# Paginator常用属性和方法 1. `count`: 总共有多少条数据。 2. `num_pages`: 总共有多少页。 3. `page_range`:页面的区间。比如有三页,那么就是`range(1,4)`。 # Page常用属性和方法: 1. `has_next`: 是否还有下一页。 2. `has_previous`: 是否还有上一页。 3. `next_page_number`: 下一页的页码。 4. `previous_page_number`: 上一页的页码。 5. `number`: 当前页。 6. `start_index`: 当前页的第一条数据的索引值。 7. `end_index`: 当前页的最后一条数据的索引值。
- article_list.html,这里我使用了bootscrip的组件样式:
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- 最新版本的 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> <ul> {% for article in articles %} <li>{{ article.title }}</li> {% endfor %} </ul> <nav aria-label="Page navigation"> <ul class="pagination"> {% if page_obj.has_previous %} <li><a href="{% url 'front:article_list' %}?page={{ page_obj.previous_page_number }}">上一页</a></li> {% else %} <li class="disabled"><a href="javascript:void(0);">上一页</a></li> {% endif %} {% if left_has_more %} <li><a href="{% url 'front:article_list' %}?page=1">1</a></li> <li><a href="javascript:void(0);">...</a></li> {% endif %} {# 左边的页码 #} {% for left_page in left_pages %} <li><a href="{% url 'front:article_list' %}?page={{ left_page }}">{{ left_page }}</a></li> {% endfor %} {# 中间的页码 #} <li><a href="{% url 'front:article_list' %}?page={{ current_page }}">{{ current_page }}</a></li> {# 右边的页码 #} {% for right_page in right_pages %} <li><a href="{% url 'front:article_list' %}?page={{ right_page }}">{{ right_page }}</a></li> {% endfor %} {% if right_has_more %} <li><a href="javascript:void(0);">...</a></li> <li><a href="{% url 'front:article_list' %}?page={{ paginator.num_pages }}">{{ paginator.num_pages }}</a></li> {% endif %} {% if page_obj.has_next %} <li><a href="{% url 'front:article_list' %}?page={{ page_obj.next_page_number }}">下一页</a></li> {% else %} <li class="disabled"><a href="javascript:void(0);">下一页</a></li> {% endif %} </ul> </nav> </body> </html>
原理基本上是将页码分成三部分,第一部分是上一页和第一页,第二部分是当前所在页前两页和后两页(共计五页),第三部分是下一页和最后一页。
- 视图函数:views.py
-
class ArticleListView(ListView): model = Article template_name = 'article_list.html' context_object_name = 'articles' paginate_by = 10 ordering = 'create_time' def get_context_data(self, **kwargs): context = super(ArticleListView, self).get_context_data(**kwargs) paginator_data = self.get_pagination_data(paginator, page_obj) context.update(paginator_data) # 将当前字典的kv更新到context字典中。 return context
# 这里来负责跳转的页码处理 def get_pagination_data(self, paginator, page_obj, around_count=2): # arount_count=2表示从当前页前推两页,后推两页 current_page = page_obj.number num_page = paginator.num_pages left_has_more = False # 左边还有没有未显示的页码 right_has_more = False # 判断当前页是不是比4小,比如当前页是第二页,他就不能存在 0.1.2.3.4这种情况。 if current_page <= around_count + 2: left_page = range(1, current_page) else: left_has_more = True left_page = range(current_page-around_count, current_page) if current_page >= num_page-around_count-1: right_page = range(current_page+1, num_page+1) else: right_has_more = True right_page = range(current_page+1, current_page+3) return { 'left_pages': left_page, 'right_pages': right_page, 'current_page': current_page, 'left_has_more': left_has_more, 'right_has_more': right_has_more, }这里定义了一个ArticleListView类,此类继承自ListView,用来处理请求等问题。
- front.urls.py,处理url跳转
-
from django.urls import path from . import views app_name = 'front' urlpatterns = [ path('add/', views.add_article, name='add'), path('list/', views.ArticleListView.as_view(), name='article_list') ]
这里我把这次的跳转放到了front app中,可以直接放到项目的urls.py中。
- 基本上就是这样,如果看不懂可以看一下我的整个项目,写的很乱,很多高级视图学习的时候的练习代码都堆在这里:https://github.com/longbigbeard/Python_Web/tree/master/Django%E7%BB%83%E4%B9%A0/views_gaoji
- 以上。