設置后的效果如下:
- 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
- 以上。