Django框架-管理後臺項目之分頁實現

1、自定義分頁

分頁功能在每一個網站都是必要的,對於分頁來講,其實就是根據用戶的輸入計算出應在數據庫表中的起始位置。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">&laquo;</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">&raquo;</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>
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>
終極html+分頁數據+指定數量分頁+搜索分頁

2、分頁功能模塊化,封裝成一個類,供全部的頁面使用

在項目下創建一個包如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
                   })

3、終極版:將搜索條件和標籤頁碼放到url下,讓標籤顯示的是篩選後的數據進行分頁

"""分頁組件"""
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

 

 4、django 實現分頁下一頁序號自增

在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}
                      )
views.py讓序號翻頁自增
相關文章
相關標籤/搜索