bootstrap-table+Django: 服務端分頁


分頁方式:

bootstrap-table提供兩種分頁方式,client和server,即客戶端和服務端分頁;

特點:

  client端分頁:后台返回所有數據,前台翻頁時不再請求后台。

  server端分頁:后台根據前台每次翻頁時傳遞的參數,進行切片查詢數據,每次只返回對應頁面的數據。

弊端:

  client端分頁:

    1、后台一次查詢所有數據,對服務器造成壓力交大;

    2、當頁面存在bootstrap-switch時,由於我是在bootstrap-table中的onLoadSuccess加載完表格后渲染switch開關,

       當使用client分頁時,只進行了一次后台查詢,也就是執行了一次onLoadSuccess函數,所以除了第一頁開關按鈕正常,其他頁面都沒有渲染出開關。

  server端分頁:

    暫無

實現代碼:

  server端分頁,前台代碼

<script type="text/javascript">

                    $('#mytab').bootstrapTable({
                        {#全部參數#}
                        //請求后台的URL(*)或者外部json文件,json內容若為json數組[{"id": 0,"name": "Item 0","price": "$0"},{"id": 1,"name": "Item 1","price": "$1"}],
                        //且鍵的名字必須與下方columns的field值一樣,同時sidePagination需要設置為client或者直接注釋掉,這樣前台才能讀取到數據,且分頁正常。
                        //當json文件內容為json對象時:{"total": 2,"rows": [{"id": 0,"name": "Item 0","price": "$0"},{"id": 1,"name": "Item 1","price": "$1"}]},
                        //分頁要寫為server,但是server如果沒有處理的話,會在第一頁顯示所有的數據,分頁插件不會起作用
                        {#url: "{% static 'guchen_obj.json' %}",     #}

                        url:"/account/user_management_data",     //從后台獲取數據時,可以是json數組,也可以是json對象
                        dataType: "json",
                        method: 'get',                      //請求方式(*)
                        toolbar: '#toolbar',                //工具按鈕用哪個容器
                        striped: true,                      //是否顯示行間隔色
                        cache: false,                       //是否使用緩存,默認為true,所以一般情況下需要設置一下這個屬性(*)
                        pagination: true,                   //是否顯示分頁(*)
                        sortable: true,                     //是否啟用排序
                        sortOrder: "asc",                   //排序方式
                        {#queryParams: oTableInit.queryParams,//傳遞參數(*)#}
                        sidePagination: "server",           //分頁方式:client客戶端分頁,server服務端分頁(*),數據為json數組時寫client,json對象時(有total和rows時)這里要為server方式,寫client列表無數據
                        pageNumber: 1,                       //初始化加載第一頁,默認第一頁
                        pageSize: 5,                       //每頁的記錄行數(*)
                        pageList: [10, 25, 50, 100],        //可供選擇的每頁的行數(*)
                        {#search: true,                       //是否顯示表格搜索,此搜索是客戶端搜索,不會進服務端,所以,個人感覺意義不大#}
                        strictSearch: true,
                        showColumns: true,                  //是否顯示所有的列
                        showRefresh: true,                  //是否顯示刷新按鈕
                        minimumCountColumns: 2,             //最少允許的列數
                        clickToSelect: true,                //是否啟用點擊選中行
                        {#height: 500,                        //行高,如果沒有設置height屬性,表格自動根據記錄條數覺得表格高度#}
                        uniqueId: "ID",                     //每一行的唯一標識,一般為主鍵列
                        showToggle: false,                    //是否顯示詳細視圖和列表視圖的切換按鈕
                        cardView: false,                    //是否顯示詳細視圖
                        detailView: false,                   //是否顯示父子表
                        idField: 'project_name',          //指定主鍵
                        singleSelect: true,                //開啟單選,想要獲取被選中的行數據必須要有該參數

                        //得到查詢的參數,會在url后面拼接,如:?rows=5&page=2&sortOrder=asc&search_kw=&_=1564105760651
                        queryParams: function (params) {
                            //這里的鍵的名字和控制器的變量名必須一直,這邊改動,控制器也需要改成一樣的
                            var query_params = {
                                rows: params.limit,                         //頁面大小
                                page: (params.offset / params.limit) + 1,   //頁碼
                                sort: params.sort,      //排序列名
                                sortOrder: params.order, //排位命令(desc,asc)

                                //查詢框中的參數傳遞給后台
                                search_kw: $('#search-keyword').val(), // 請求時向服務端傳遞的參數
                            };
                            return query_params;
                        },

                        columns: [
                            {
                                checkbox:true  //第一列顯示復選框
                             },

                            {
                                field: 'member_code',  //返回數據rows數組中的每個字典的鍵名與此處的field值要保持一致
                                title: '工號'
                            },
                            {
                                field: 'name',
                                title: '姓名'
                             },
                            {
                                field: 'role',
                                title: '角色'
                             },
                            {
                                field: 'create_time',
                                title: '創建時間'
                            },
                            {
                                field: 'status',
                                title: '狀態',
                                formatter: user_status,
                            },
                            {
                                field: 'operate',
                                title: '操作',
                                width: 120,
                                align: 'center',
                                valign: 'middle',
                                formatter: actionFormatter,
                             },
                        ],

                        onLoadSuccess: function(data){
                             {#獲取行數據的狀態#}
                            console.log('渲染數據完成后,打印所有數據')
                            console.log(data);
                            {#獲取所有列表數據#}
                            var data=$("#mytab").bootstrapTable("getData");
                            console.log('已獲取全部數據%s',data);
                            {#根據每行數據的status值渲染開關#}
                            for (var i=0;i<data.length;i++){
                                console.log(data[i].project_id,data[i].status)
                                if (data[i].status == 1){
                                    console.log('這個是開啟的')
                                    $("[id='project_status_switch_on']").bootstrapSwitch({
                                        onText: "啟用",      // 設置ON文本  
                                        offText: "禁用",    // 設置OFF文本  
                                        onColor: "success",// 設置ON文本顏色(info/success/warning/danger/primary)  
                                        offColor: "danger",  // 設置OFF文本顏色 (info/success/warning/danger/primary)  
                                        size: "small",    // 設置控件大小,從小到大  (mini/small/normal/large)
                                        // 當開關狀態改變時觸發  
                                        onSwitchChange : function(event, state) {  
                                            console.log(state);
                                            {#獲取該行的project_id#}
                                            var project_id = this.value;
                                            console.log(project_id);
                                            if (state == false) {
                                                status=1
                                                {#alert("ON");#}
                                                console.log(status);
                                                set_status(project_id, status);
                                            } else {
                                                status=0
                                                {#alert("OFF");#}
                                                set_status(project_id, status);
                                            }  
                                         }  
                                    })
                                }else{
                                    console.log('這個是禁用的')
                                    $("[id='project_status_switch_off']").bootstrapSwitch({
                                        onText: "啟用",      // 設置ON文本  
                                        offText: "禁用",    // 設置OFF文本  
                                        onColor: "success",// 設置ON文本顏色(info/success/warning/danger/primary)  
                                        offColor: "danger",  // 設置OFF文本顏色 (info/success/warning/danger/primary)  
                                        size: "small",    // 設置控件大小,從小到大  (mini/small/normal/large)
                                        // 當開關狀態改變時觸發  
                                        onSwitchChange : function(event, state) {  
                                            console.log(state);
                                            {#獲取該行的project_id#}
                                            var project_id = this.value;
                                            console.log(project_id);
                                            if (state == false) {
                                                status=1
                                                {#alert("ON");#}
                                                console.log(status);
                                                set_status(project_id, status);
                                            } else {
                                                status=0
                                                {#alert("OFF");#}
                                                set_status(project_id, status);
                                            }  
                                         }  
                                    })
                                }
                            }
                        }

                    });


                //操作欄的格式化,value代表當前單元格中的值,row代表當前行數據,index表示當前行的下標
                function actionFormatter(value, row, index) {
                    var id = index;
                    var data = JSON.stringify(row);
                    var result = "";
                    {#result += "<a href='javascript:;' class='btn btn-xs green' onclick=\"EditViewById('" + id + "', view='view')\" title='查看'><span class='glyphicon glyphicon-search'></span></a>";#}
                    {#result += "<a href='javascript:;' class='btn btn-xs blue' onclick=\"EditViewById('" + JSON.stringify(row) + "','" + id + "')\" title='編輯'><span class='glyphicon glyphicon-pencil'></span></a>";#}
                    result += "<a href='javascript:;' class='btn btn-xs blue' onclick=\"EditViewById('" + row + "','" + id + "')\" title='編輯'><span class='glyphicon glyphicon-pencil'></span></a>";
                    {#result += "<a href='javascript:;' class='btn btn-xs blue' onclick=\"edit()\" title='編輯'><span class='glyphicon glyphicon-pencil'></span></a>";#}
                    {#result += "<a href='javascript:;' class='btn btn-xs red' onclick=\"DeleteByIds('" + id + "')\" title='刪除'><span class='glyphicon glyphicon-remove'></span></a>";#}
                    return result;

                }

                {#狀態欄格式化,根據該行數據的status的值控制checked屬性是否選中#}
                function user_status(value, row, index) {
                    var data = JSON.stringify(row); //獲取該行數據
                    var data_json = JSON.parse(data);
                    console.log(data_json);
                    console.log('格式化最先被執行')
                    {#for (var i=0;i<data_json.length;i++){#}
                    {#    console.log('第%s行的狀態為%s',i,data_json.status);#}

                    if (data_json.status == 1) {
                        console.log('設置為開啟')
                        return "<input value='"+data_json.project_id+"' type='checkbox' checked id='project_status_switch_on' name='mycheck'>";

                    } else {
                        console.log('設置為關閉')
                        return "<input value='"+data_json.project_id+"' type='checkbox'  id='project_status_switch_off' name='mycheck'>";
                    }
                }

                // 搜索查詢按鈕觸發事件
                $(function() {
                    $("#search-button").click(function () {
                        $('#mytab').bootstrapTable(('refresh')); // 很重要的一步,刷新url!
                        $('#search-keyword').val()
                    })
                })

                //重置搜索條件
                function clean(){
                    //先清空
                    $('#search-keyword').val('');
                    //清空后查詢條件為空了,再次刷新頁面,就是全部數據了
                    $('#mytab').bootstrapTable(('refresh')); // 很重要的一步,刷新url!
                }

        </script>

 

 

 server端分頁,后台代碼

def user_management_data(request):
    """
    如果是get請求則只展示用戶數據,
    post請求新增用戶
    :param request:
    :return:
    """
    if request.method == 'GET':
        search_kw = request.GET.get('search_kw', None)
        print search_kw
        # 獲取分頁參數用於查詢對應頁面數據,page為第幾頁,num為每頁數據條數,right_boundary為數據切片的右側邊界
        page = request.GET.get('page')
        num = request.GET.get('rows')
        right_boundary = int(page)*int(num)
        print page,num,int(page)*int(num)
        # 如果搜索關鍵字不為空,則根據此關鍵字模糊查詢工號和姓名
        if search_kw:
           page_user = User.objects.filter(Q(member_code__contains=search_kw) | Q(name__contains=search_kw))[int(num)*(int(page)-1):right_boundary]
           # 獲取查詢結果的總條數
           total = User.objects.filter(Q(member_code__contains=search_kw) | Q(name__contains=search_kw)).count()
           print '查詢結果總數為:%s' % total
        else:
            # 根據前台傳來的分頁信息,頁碼(page)和每頁條數(rows),計算分頁后的user對象片段,例如前台傳來第2頁的參數,
            # rows=10,page=2,則服務端需要給前台返回[10:20]的數據片段,切片是左閉右開,所以最大只會取到下標為10到19,共10個數據
            page_user = User.objects.all()[int(num)*(int(page)-1):right_boundary]
            # server端分頁時必須返回total和rows,total用於分頁時顯示總數
            total = User.objects.all().count()
        # rows為具體數據
        rows = []
        # 遍歷查詢出的user對象,將對應數據放到rows中
        for user in page_user:
            rows.append({'member_code': user.member_code, 'name': user.name, 'role': user.role_name.role_name, 'create_time': user.create_time, 'status': user.status})
        print rows
        # return render(request, 'account/user_management.html', {'rows': json.dumps(rows, cls=DateEncoder)})
        # 序列化數據,因為有datetime類型數據,所以使用自定義類DateEncoder序列化
        return HttpResponse(json.dumps({'total': total, 'rows': rows}, cls=DateEncoder))

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM