分頁功能在每一個網站都是必要的,對於分頁來講,其實就是根據用戶的輸入計算出應在數據庫表中的起始位置。javascript
一、設定煤業顯示的數據條數css
二、用戶輸入頁碼(第一頁,第二頁...)html
三、根據設定的每頁顯示條數和當前頁碼,計算出須要取數據表的起始位置前端
四、在數據表中根據起始位置取值,頁面上輸出數據java
前面那樣會在頁面中生成全部的頁碼,但實際須要是設定指定數量的頁碼,格式如 [上一頁][1][2][3][4][5][下一頁]jquery
一、設定每頁顯示數據條數數據庫
二、用戶輸入頁碼django
三、設定顯示多少頁號bootstrap
四、獲取當前數據總條數後端
五、根據設定顯示多少頁號和數據總條數計算出總頁數
六、根據設定的每頁顯示條數和當前頁碼數,計算出須要取數據表的起始位置
七、在數據表中根據起始位置取值,頁面上輸出數據
八、輸出分頁html,如:[上一頁][1][2][3][4][5][下一頁]
urls.py
urlpatterns = [ url(r'page/, views.page), ]
customer.html
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" href="{% static 'imgs/aimp_logo_48px_.ico' %}"> {% block title %} {#下面的是改網頁的標題上的圖標#} <title>Template</title> {% endblock %} <!-- Bootstrap core CSS --> <link href="{% static 'plugin/bootstrap3.7/css/bootstrap.min.css' %}" rel="stylesheet"> <!-- font_awesome CSS --> <link rel="stylesheet" href="{% static 'plugin/font-awesome-4.7.0/css/font-awesome.min.css' %}"> <!-- Custom styles for this template網上模板定義的css樣式 --> <link href="{% static 'css/dashboard.css' %}" rel="stylesheet"> {% block custom_css %} {#自定義css留白#} {% endblock %} </head> <body> {#導航組件#} {% include 'layout/navbar.html' %} {#內容區#} <div class="container-fluid"> <div class="row"> {#左側邊欄#} <div class="col-sm-3 col-md-2 sidebar"> <ul class="nav nav-sidebar"> <li class="active"><a href="{% url 'app_crm:customer_list' %}">客戶信息表 <span class="sr-only">(current)</span></a></li> <li><a href="#">銷售</a></li> <li><a href="#">老師</a></li> <li><a href="#">學生</a></li> </ul> </div> {#右邊內容展現區,表單及面板#} <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main"> {% block content %} <h2 class="sub-header">客戶信息展現表</h2> <div class="table-responsive"> <table class="table table-striped"> <thead> <tr> <th>序號</th> <th>帳戶</th> <th>密碼</th> </tr> </thead> <tbody> {% for u in user %} <tr> <td>{{ forloop.counter }}</td> <td>{{ u.name }}</td> <td>{{ u.pwd }}</td> </tr> {% empty %} <tr> <td colspan="3" class="text-center">暫無數據</td> </tr> {% endfor %} </tbody> </table> {# 分頁 #} <nav aria-label="Page navigation" class="text-center"> <ul class="pagination"> <li> <a href="#" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> {% for page in total_page %} {# 此處也能夠設計url爲分組的形式傳遞頁碼給後臺{% url 'app_crm:base' page %}#} <li><a href="{% url 'app_crm:base' %}?page={{ page }}">{{ page }}</a></li> {% endfor %} <li> <a href="#" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav> </div> {% endblock %} </div> </div> </div> <!-- Bootstrap core JavaScript --> <!-- Placed at the end of the document so the pages load faster --> <script type="text/javascript" src="{% static 'plugin/jquery-3.3.1/jquery3.3.1.min.js' %}"></script> <script type="text/javascript" src="{% static 'plugin/bootstrap3.7/js/bootstrap.min.js' %}"></script> {#自定義js留白區域快#} {% block custom_js %} {% endblock %} </body> </html>
views.py
1 def page(request): 2 """ 3 all_count: 總數據條數 4 page_num: 每頁顯示數據條數,自定義 5 total_page: 總頁碼數 6 more:總數據條數% 每頁數 ==》餘數 7 current_page: 當前頁碼,由前端點擊時,將頁碼發回來 8 """ 9 user = [{'name': 'sun%s' % i, 'pwd': 'pwd{}'.format(i)} for i in range(1, 302)] # 測試數據源 10 all_count = len(user) # 拿到總數據條數 11 page_num = 10 # 定義每頁顯示的數據條數 12 total_page, more = divmod(all_count, page_num) # 得出商和餘數 13 if more: # 若是有餘數,表示總頁碼要多加一個頁碼,不然就是整除 14 total_page += 1 15 16 try: 17 current_page = int(request.GET.get('page')) 18 if current_page <= 0: # 由於不肯定前端傳過來的數字的準確性,可能沒有或超過,負數因此要判斷,一旦報錯,就設置當前頁爲1 19 raise ValueError() 20 except Exception as e: 21 current_page = 1 22 23 # 全部數據和生成的標籤頁所有展現 24 # 由於計劃經過前端for循環產生標籤,故須要傳一個可迭代的數據即range(1,total_page+1),切片取頭不取尾 25 return render(request, 'layout/base.html', {'user': user, 'total_page': range(1, total_page + 1)}) 26 27 # 注:前端拿到user和total_page對象,對其for循環生成對應標籤便可
1 def page(request): 2 """ 3 all_count: 總數據條數 4 page_num: 每頁顯示數據條數,自定義 5 total_page: 總頁碼數 6 more:總數據條數% 每頁數 ==》餘數 7 current_page: 當前頁碼,由前端點擊時,將頁碼發回來 8 start: 切片開始索引 9 end: 切片結束索引 10 頁碼數和切片之間的關係: 11 第一頁: 1 1 10 0 10 每頁10條,切片從0開始,尾不取 12 2 11 20 10 20 13 3 21 30 20 30 14 關係爲:(當前頁-1)*10 即 start = (current_page-1)*10 15 end= current_page*page_num 16 """ 17 user = [{'name': 'sun%s' % i, 'pwd': 'pwd{}'.format(i)} for i in range(1, 302)] 18 all_count = len(user) 19 page_num = 10 # 定義每頁顯示的數據條數 20 total_page, more = divmod(all_count, page_num) # 得出商和餘數 21 if more: # 若是有餘數,表示總頁碼要多加一個頁碼,不然就是整除 22 total_page += 1 23 try: 24 current_page = int(request.GET.get('page')) 25 # 由於不肯定前端傳過來的數字的準確性,可能沒有或超過,負數因此要判斷,一旦報錯,就設置當前頁爲1 26 if current_page <= 0: 27 raise ValueError() 28 except Exception as e: 29 current_page = 1 30 # 根據前端傳過來的頁碼,計算給前端發送多少數據,限制數據條數 31 start = (current_page - 1) * 10 32 end = current_page * page_num 33 34 return render(request, 'layout/base.html', {'user': user[start:end], # 限制數據條數,根據須要給 35 'total_page': range(1, total_page + 1)})
def page(request): """ all_count: 總數據條數 page_num: 每頁顯示數據條數,自定義 total_page: 總頁碼數 more:總數據條數% 每頁數 ==》餘數 current_page: 當前頁碼,由前端點擊時,將頁碼發回來 start: 切片開始索引 end: 切片結束索引 頁碼數和切片之間的關係: 第一頁: 1 1 10 0 10 每頁10條,切片從0開始,尾不取 2 11 20 10 20 3 21 30 20 30 關係爲:(當前頁-1)*10 即 start_page = (current_page-1)*10 end_page = current_page*page_num start_page: 起始頁碼數 end_page: 終止頁碼數 max_page_show: 每頁最多展現幾個分頁,如7各分頁:1 2 3 當前頁 5 6 7 """ user = [{'name': 'sun%s' % i, 'pwd': 'pwd{}'.format(i)} for i in range(1, 302)] all_count = len(user) page_num = 10 # 定義每頁顯示的數據條數 total_page, more = divmod(all_count, page_num) # 得出商和餘數 if more: # 若是有餘數,表示總頁碼要多加一個頁碼,不然就是整除 total_page += 1 # 由於計劃經過前端for循環產生標籤,故須要傳一個可迭代的數據即range(1,total_page+1),切片取頭不取尾 try: current_page = int(request.GET.get('page')) # 由於不肯定前端傳過來的數字的準確性,可能沒有或超過,負數因此要判斷,一旦報錯,就設置當前頁爲1 if current_page <= 0: raise ValueError() except Exception as e: current_page = 1 # 根據前端傳過來的頁碼,計算給前端發送多少數據,限制數據條數 start = (current_page - 1) * 10 end = current_page * page_num # 定義分頁頁碼起始頁碼數,終止頁碼數,每一個頁面最大顯示頁碼數 max_page_show = 5 # 通常都定義爲奇數,讓中間的頁(即當前頁)左右對稱 half_page_show = max_page_show // 2 # 將會出現幾種狀況: # 一、數據總頁碼數<= 定義的每一個頁面最大顯示頁碼數max_page_show,就直接把全部的顯示出來便可 if total_page <= max_page_show: start_page = 1 end_page = total_page else: # 二、當前頁小於half_page_show時,排除會出現負數的狀況,解決左邊的問題 if current_page <= half_page_show: # 都要保證每一個頁面有max_page_show頁 start_page = 1 end_page = max_page_show # 三、當前頁+half_page_show > max_page_show 時,會出現沒有數據,但會有頁碼,故須要排除掉 elif current_page + half_page_show > total_page: start_page = total_page - max_page_show + 1 # start_page = current_page - half_page_show +1 end_page = total_page else: start_page = current_page - half_page_show end_page = current_page + half_page_show return render(request, 'layout/base.html', {'user': user[start:end], 'total_page': range(start_page, end_page + 1) }) # 限制頁面總顯示頁碼數及根據需求頁碼給出對應數據
from django.shortcuts import render, reverse def base(request): """ all_count: 總數據條數 page_num: 每頁顯示數據條數,自定義 total_page: 總頁碼數 more:總數據條數% 每頁數 ==》餘數 current_page: 當前頁碼,由前端點擊時,將頁碼發回來 start: 切片開始索引 end: 切片結束索引 頁碼數和切片之間的關係: 第一頁: 1 1 10 0 10 每頁10條,切片從0開始,尾不取 2 11 20 10 20 3 21 30 20 30 關係爲:(當前頁-1)*10 即 start_page = (current_page-1)*10 end_page = current_page*page_num start_page: 起始頁碼數 end_page: 終止頁碼數 max_page_show: 每一個頁面最大顯示頁碼數,如7各分頁:1 2 3 當前頁 5 6 7 """ user = [{'name': 'sun%s' % i, 'pwd': 'pwd{}'.format(i)} for i in range(1, 302)] all_count = len(user) # 得出數據總條數 page_num = 10 # 定義每頁顯示的數據條數 total_page, more = divmod(all_count, page_num) # 得出商和餘數 if more: total_page += 1 # 若是有餘數,表示總頁碼要多加一個頁碼 try: current_page = int(request.GET.get('page')) # 由於不肯定前端傳過來的數字的準確性,可能沒有或超過,負數,因此要判斷,一旦報錯,就設置當前頁爲1 if current_page <= 0: raise Exception('當前頁碼數字不符合規範') except Exception as e: current_page = 1 # 根據前端傳過來的頁碼,計算給前端發送多少數據,限制數據條數 start = (current_page - 1) * page_num end = current_page * page_num # 定義分頁頁碼起始頁碼數,終止頁碼數,每一個頁面最大顯示頁碼數,實現每頁固定頁碼數 max_page_show = 5 # 通常都定義爲奇數,讓中間的頁(即當前頁)左右對稱 half_page_show = max_page_show // 2 # 一、數據總頁碼數<= 定義的每一個頁面最大顯示頁碼數max_page_show,就直接把全部的顯示出來便可 if total_page <= max_page_show: start_page = 1 end_page = total_page else: # 二、當前頁小於half_page_show時,排除會出現負數的狀況,解決左邊的問題 if current_page <= half_page_show: # 都要保證每一個頁面有max_page_show頁 start_page = 1 end_page = max_page_show # 三、當前頁+half_page_show > max_page_show 時,會出現沒有數據,但會有頁碼,故須要排除掉 elif current_page + half_page_show > total_page: start_page = total_page - max_page_show + 1 # start_page = current_page - half_page_show +1 end_page = total_page else: start_page = current_page - half_page_show end_page = current_page + half_page_show """後端實現分頁,前端只需接收只需接收字符串便可,故須要把生成得標籤拼接起來""" html_list = [] # 加上"首頁"功能,即當前頁與第一頁相比【首頁】【上一頁】 1 2 3 4 5 【下一頁】【末頁】 if current_page <= 1: first = '<li class="disabled"><a>首頁</a></li>' else: first = '<li><a href="{}?page={}">首頁</a></li>'.format(reverse('app_crm:base'), 1) html_list.append(first) # 加上"上一頁"功能,即當前頁與第一頁相比 【首頁】【上一頁】 1 2 3 4 5 【下一頁】【末頁】 if current_page <= 1: prev = '<li class="disabled"><a>上一頁</a></li>' # 當前頁小於1時,上一頁按鈕禁止點擊 else: prev = '<li><a href="{}?page={}">上一頁</a></li>'.format(reverse('app_crm:base'), current_page - 1) html_list.append(prev) # 生成分頁頁碼標籤 for page in range(start_page, end_page + 1): if page == current_page: # 加active類 li_html = '<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(reverse('app_crm:base'), page) else: li_html = '<li><a href="{0}?page={1}">{1}</a></li>'.format(reverse('app_crm:base'), page) html_list.append(li_html) # 加上"下一頁"功能,當前頁與最後一頁比較,即total_page if current_page >= total_page: next_page = '<li class="disabled"><a>下一頁</a></li>' else: next_page = '<li><a href="{}?page={}">下一頁</a></li>'.format(reverse('app_crm:base'), current_page + 1) html_list.append(next_page) # 加上"末頁" 功能 if current_page >= total_page: last = '<li class="disabled"><a>末頁</a></li>' else: last = '<li><a href="{}?page={}">末頁</a></li>'.format(reverse('app_crm:base'), total_page) html_list.append(last) html_str = "".join(html_list) # 拼接成字符串 from django.utils.html import format_html # 後端聲明發送的是安全的標籤,將字符串編譯成標籤 result = format_html(html_str) return render(request, 'layout/base.html', {'user': user[start:end], 'total_page': result }) # 限制頁面總顯示頁碼數及根據需求頁碼給出對應數據
分頁終極版是在後端循環生成分頁標籤,故前端只需引用便可{{result}} 便可。
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 上述3個meta標籤*必須*放在最前面,任何其餘內容都*必須*跟隨其後! --> <link rel="icon" href="{% static 'imgs/aimp_logo_48px_.ico' %}"> {% block title %} <title>Template</title> {% endblock %} <!-- Bootstrap core CSS --> <link href="{% static 'plugin/bootstrap3.7/css/bootstrap.min.css' %}" rel="stylesheet"> <!-- font_awesome CSS --> <link rel="stylesheet" href="{% static 'plugin/font-awesome-4.7.0/css/font-awesome.min.css' %}"> <!-- Custom styles for this template網上模板定義的css樣式 --> <link href="{% static 'css/dashboard.css' %}" rel="stylesheet"> {% block custom_css %} {#自定義css留白#} {% endblock %} </head> <body> {#導航組件#} {% include 'layout/navbar.html' %} {#內容區#} <div class="container-fluid"> <div class="row"> {#左側邊欄#} <div class="col-sm-3 col-md-2 sidebar"> <ul class="nav nav-sidebar"> <li class="active"><a href="{% url 'app_crm:customer_list' %}">客戶信息表 <span class="sr-only">(current)</span></a></li> <li><a href="#">銷售</a></li> <li><a href="#">老師</a></li> <li><a href="#">學生</a></li> </ul> </div> {#右邊內容展現區#} <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main"> {% block content %} <h2 class="sub-header">客戶信息展現表</h2> <div class="table-responsive"> <table class="table table-striped"> <thead> <tr> <th>序號</th> <th>帳戶</th> <th>密碼</th> </tr> </thead> <tbody> {% for u in user %} <tr> <td>{{ forloop.counter }}</td> <td>{{ u.name }}</td> <td>{{ u.pwd }}</td> </tr> {% empty %} <tr> <td colspan="3" class="text-center">暫無數據</td> </tr> {% endfor %} </tbody> </table> {# 分頁 #} <nav aria-label="Page navigation" class="text-center"> <ul class="pagination"> {{ total_page }} </ul> <form action=""> <span>去第</span> <label for="search_page"></label> <input id="search_page" name="page" type="text" > <span>頁</span> <input type="submit" class=" btn-primary" value="肯定"> </form> </nav> </div> {% endblock %} </div> </div> </div> <script type="text/javascript" src="{% static 'plugin/jquery-3.3.1/jquery3.3.1.min.js' %}"></script> <script type="text/javascript" src="{% static 'plugin/bootstrap3.7/js/bootstrap.min.js' %}"></script> {% block custom_js %} {#自定義js留白區域快#} {% endblock %} </body> </html>
在項目下創建一個包如utils,在裏面創建一個py文件,如命名分頁組件: pagination.py
封裝成分頁組件,須要導入傳參便可用
"""分頁組件""" from django.utils.html import format_html # 後端聲明發送的是安全的標籤,將字符串編譯成標籤 class Pagination(object): """ all_count: 總數據條數 page_num: 每頁顯示數據條數,自定義 total_page: 總頁碼數 more:總數據條數% 每頁數 ==》餘數 current_page: 當前頁碼,由前端點擊時,將頁碼發回來 start: 切片開始索引 end: 切片結束索引 頁碼數和切片之間的關係: 第一頁: 1 1 10 0 10 每頁10條,切片從0開始,尾不取 2 11 20 10 20 3 21 30 20 30 關係爲:(當前頁-1)*10 即 start_page = (current_page-1)*10 end_page = current_page*page_num start_page: 起始頁碼數 end_page: 終止頁碼數 max_page_show: 每一個頁面最大顯示頁碼數,如7各分頁:1 2 3 當前頁 5 6 7 通常都定義爲奇數,讓中間的頁(即當前頁)左右對稱 base_url : 訪問url地址 """ def __init__(self, request, base_url, all_count, page_num=10, max_page_show=5): # 獲取需求頁碼 try: current_page = int(request.GET.get('page')) if current_page <= 0: raise Exception('當前頁碼數字不符合規範') except Exception as e: current_page = 1 # 定義分頁頁碼起始頁碼數,終止頁碼數,每一個頁面最大顯示頁碼數,實現每頁固定頁碼數 self.max_page_show = max_page_show self.half_page_show = max_page_show // 2 self.current_page = current_page self.all_count = all_count self.page_num = page_num self.base_url = base_url # 計算數據總條數 self.total_page, more = divmod(self.all_count, self.page_num) # 得出商和餘數 if more: self.total_page += 1 # 若是有餘數,表示總頁碼要多加一個頁碼 @property def start(self): # 根據前端傳過來的頁碼,計算給前端發送多少數據,限制數據條數 # 數據切片的起始索引和終止索引 return (self.current_page - 1) * self.page_num @property def end(self): return self.current_page * self.page_num @property def html_str(self): # 計算起始頁碼數和終止頁碼數 # 一、數據總頁碼數<= 定義的每一個頁面最大顯示頁碼數max_page_show,就直接把全部的顯示出來便可 if self.total_page <= self.max_page_show: start_page = 1 end_page = self.total_page else: # 二、當前頁小於half_page_show時,排除會出現負數的狀況,解決左邊的問題 if self.current_page <= self.half_page_show: # 都要保證每一個頁面有max_page_show頁 start_page = 1 end_page = self.max_page_show # 三、當前頁+half_page_show > max_page_show 時,會出現沒有數據,但會有頁碼,故須要排除掉 elif self.current_page + self.half_page_show > self.total_page: start_page = self.total_page - self.max_page_show + 1 # start_page = current_page - half_page_show +1 end_page = self.total_page else: start_page = self.current_page - self.half_page_show end_page = self.current_page + self.half_page_show """後端實現分頁,前端只需接收只需接收字符串便可,故須要把生成得標籤拼接起來""" html_list = [] # 加上"首頁"功能,即當前頁與第一頁相比【首頁】【上一頁】 1 2 3 4 5 【下一頁】【末頁】 if self.current_page <= 1: first = '<li class="disabled"><a>首頁</a></li>' else: first = '<li><a href="{}?page={}">首頁</a></li>'.format(self.base_url, 1) html_list.append(first) # 加上"上一頁"功能,即當前頁與第一頁相比 【首頁】【上一頁】 1 2 3 4 5 【下一頁】【末頁】 if self.current_page <= 1: prev = '<li class="disabled"><a><上一頁></a></li>' # 當前頁小於1時,上一頁按鈕禁止點擊 else: prev = '<li><a href="{}?page={}"><上一頁></a></li>'.format(self.base_url, self.current_page - 1) html_list.append(prev) # 生成分頁頁碼標籤 for page in range(start_page, end_page + 1): if page == self.current_page: # 加active類 li_html = '<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, page) else: li_html = '<li><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, page) html_list.append(li_html) # 加上"下一頁"功能,當前頁與最後一頁比較,即total_page if self.current_page >= self.total_page: next_page = '<li class="disabled"><a><下一頁></a></li>' else: next_page = '<li><a href="{}?page={}"><下一頁></a></li>'.format(self.base_url, self.current_page + 1) html_list.append(next_page) # 加上"末頁" 功能 if self.current_page >= self.total_page: last = '<li class="disabled"><a>末頁</a></li>' else: last = '<li><a href="{}?page={}">末頁</a></li>'.format(self.base_url, self.total_page) html_list.append(last) html_str = "".join(html_list) # 拼接成字符串 result = format_html(html_str) return result
此分頁組件,項目下全部的app均可以使用,主要傳參 request, base_url, all_count, page_num=10, max_page_show=5,
分別爲request,目標url,全部的數據條數,每頁顯示最大數據條數,默認10條,每頁最多顯示分頁標籤數,默認5個
在app應用的views.py中引用:
from utils.pagination import Pagination
def base_test(request): base_url = request.path_info # 獲取當前url,也能夠自定義 page_obj = Pagination(request, base_url, len(users), 15, 11) total_page = page_obj.total_page return render(request, 'layout/base.html', {'user_list': users[page_obj.start:page_obj.end], 'result': page_obj.html_str, 'total_page':total_page })
"""分頁組件""" from django.utils.html import format_html # 後端聲明發送的是安全的標籤,將字符串編譯成標籤 class Pagination(object): """ all_count: 總數據條數 page_num: 每頁顯示數據條數,自定義 total_page: 總頁碼數 more:總數據條數% 每頁數 ==》餘數 current_page: 當前頁碼,由前端點擊時,將頁碼發回來 start: 切片開始索引 end: 切片結束索引 頁碼數和切片之間的關係: 第一頁: 1 1 10 0 10 每頁10條,切片從0開始,尾不取 2 11 20 10 20 3 21 30 20 30 關係爲:(當前頁-1)*10 即 start_page = (current_page-1)*10 end_page = current_page*page_num start_page: 起始頁碼數,一個頁面中顯示的分頁標籤 end_page: 終止頁碼數 max_page_show: 每一個頁面最大顯示頁碼數,如7各分頁:1 2 3 當前頁 5 6 7 通常都定義爲奇數,讓中間的頁(即當前頁)左右對稱 base_url : 當前訪問url地址 query_params: 爲了分頁標籤能帶上搜索條件,讓分頁數據是從搜索條件來的 搜索和分頁要合併起來,否則搜索到對應數據,展現出來,但一旦點擊分頁標籤,就會走分頁的邏輯,不是拿搜索中的數據 來分頁,因此應該爲分頁標籤加上搜索條件,當發點擊搜索get請求後,會先走搜索,將篩選後的數據類表傳給分頁函數,再分頁, 當點擊分頁標籤時會再次搜索,而後分頁,而不是搜索條件爲空,展現全部的數據 """ def __init__(self, request, base_url, all_count, page_num=10, max_page_show=5): # 獲取需求頁碼 try: current_page = int(request.GET.get('page')) if current_page <= 0: raise Exception('當前頁碼數字不符合規範') except Exception as e: current_page = 1 # 定義分頁頁碼起始頁碼數,終止頁碼數,每一個頁面最大顯示頁碼數,實現每頁固定頁碼數 self.max_page_show = max_page_show self.half_page_show = max_page_show // 2 self.current_page = current_page self.all_count = all_count self.page_num = page_num self.base_url = base_url # 爲了分頁與搜索條件合併 # request.GET.urlencode() 方法能夠將url中?後面的查詢條件按key=value完成拿出來 query=3 # url合成格式爲:?query=3&page=x # import copy # query_params = copy.deepcopy(request.GET) # 是一個querySet字典,爲防止對request.GET 的改變影響其它方法的調用,對其深拷貝 # django自帶的深拷貝方法 query_params = request.GET.copy() self.query_params = query_params self.query_params._mutable = True # 容許querySet字典變動 # 計算數據總條數 self.total_page, more = divmod(self.all_count, self.page_num) # 得出商和餘數 if more: self.total_page += 1 # 若是有餘數,表示總頁碼要多加一個頁碼 @property def start(self): # 根據前端傳過來的頁碼,計算給前端發送多少數據,限制數據條數 # 數據切片的起始索引和終止索引 return (self.current_page - 1) * self.page_num @property def end(self): return self.current_page * self.page_num @property def html_str(self): # 計算起始頁碼數和終止頁碼數 # 一、數據總頁碼數<= 定義的每一個頁面最大顯示頁碼數max_page_show,就直接把全部的顯示出來便可 if self.total_page <= self.max_page_show: start_page = 1 end_page = self.total_page else: # 二、當前頁小於half_page_show時,排除會出現負數的狀況,解決左邊的問題 if self.current_page <= self.half_page_show: # 都要保證每一個頁面有max_page_show頁 start_page = 1 end_page = self.max_page_show # 三、當前頁+half_page_show > max_page_show 時,會出現沒有數據,但會有頁碼,故須要排除掉 elif self.current_page + self.half_page_show > self.total_page: start_page = self.total_page - self.max_page_show + 1 # start_page = current_page - half_page_show +1 end_page = self.total_page else: start_page = self.current_page - self.half_page_show end_page = self.current_page + self.half_page_show """後端實現分頁,前端只需接收只需接收字符串便可,故須要把生成得標籤拼接起來""" html_list = [] # 加上"首頁"功能,即當前頁與第一頁相比【首頁】【上一頁】 1 2 3 4 5 【下一頁】【末頁】 if self.current_page <= 1: first = '<li class="disabled"><a>首頁</a></li>' else: self.query_params['page'] = 1 # first = '<li><a href="{}?page={}">首頁</a></li>'.format(self.base_url, 1) # 爲了search和page合併將page加入到query_params字典中,而後query_params.urlencode()拼接 first = '<li><a href="{}?{}">首頁</a></li>'.format(self.base_url, self.query_params.urlencode()) html_list.append(first) # 加上"上一頁"功能,即當前頁與第一頁相比 【首頁】【上一頁】 1 2 3 4 5 【下一頁】【末頁】 if self.current_page <= 1: prev = '<li class="disabled"><a><上一頁></a></li>' # 當前頁小於1時,上一頁按鈕禁止點擊 else: self.query_params['page'] = self.current_page - 1 prev = '<li><a href="{}?{}"><上一頁></a></li>'.format(self.base_url, self.query_params.urlencode()) html_list.append(prev) # 生成分頁頁碼標籤 for page in range(start_page, end_page + 1): self.query_params['page'] = page if page == self.current_page: # 加active類 li_html = '<li class="active"><a href="{}?{}">{}</a></li>'.format(self.base_url, self.query_params.urlencode(), page) else: li_html = '<li><a href="{}?{}">{}</a></li>'.format(self.base_url, self.query_params.urlencode(), page) html_list.append(li_html) # 加上"下一頁"功能,當前頁與最後一頁比較,即total_page if self.current_page >= self.total_page: next_page = '<li class="disabled"><a><下一頁></a></li>' else: self.query_params['page'] = self.current_page + 1 next_page = '<li><a href="{}?{}"><下一頁></a></li>'.format(self.base_url, self.query_params.urlencode()) html_list.append(next_page) # 加上"末頁" 功能 if self.current_page >= self.total_page: last = '<li class="disabled"><a>末頁</a></li>' else: self.query_params['page'] = self.total_page last = '<li><a href="{}?{}">末頁</a></li>'.format(self.base_url, self.query_params.urlencode()) html_list.append(last) html_str = "".join(html_list) # 拼接成字符串 result = format_html(html_str) return result
在django模板中分頁時使用{{forloop.counter }}生成序號時,點擊下一頁,序號依舊從1開始
{% for row in user_set%} <li>{{forloop.counter}}--{{ row.username }}</li> {% endfor %}
解決辦法:views.py向模板發送
strat=(current_page-1)*count_page
#current_page爲當前頁碼數,count_page爲每頁顯示數量
#其實已經在自定義分頁寫好了,只用拿來發送給模板就能夠
render(request,"user_info.html",{"user_set": date,"strat":strat}) 此時模板中的{{forloop.counter }}改成{{forloop.counter|add:strat }} 就能夠實如今第二頁以後每一頁自增
class ConsultRecordList(BatchOperationMethod): def get(self, request, *args, customer_id='0', ): query_list = ['note'] q = self.multi_search_conditions(request, query_list) if customer_id == '0': # 規定customer_id =0,拿全部記錄 from django.db.models import Max # 獲取用戶最後的一條記錄 customer_last_record_list = models.ConsultRecord.objects.filter(q, consultant=request.user).values( 'customer').annotate(Max('id')) consult_record_info_list = [] for i in customer_last_record_list: # 獲取每一個客戶最後跟進記錄的對象 recod_obj = models.ConsultRecord.objects.filter(id=i['id__max']).first() consult_record_info_list.append(recod_obj) else: consult_record_info_list = models.ConsultRecord.objects.filter( q, consultant=request.user, customer_id=customer_id ).order_by('-date') # 添加 add_btn, next_url = self.get_add_btn(request, reverse('consult_record_add')) # 分頁 page_obj = Pagination(request, reverse('consult_record', args=(customer_id,)), len(consult_record_info_list), settings.PAGE_MAX_SHOW, settings.PAGE_NUM ) return render(request, 'customer/consult_records.html', {'consult_record_info_list': consult_record_info_list[page_obj.start:page_obj.end], 'html_str': page_obj.html_str, 'total_page': page_obj.total_page, 'start': page_obj.start, 'add_btn': add_btn, 'next_url': next_url} )