1. 程式人生 > >DjangoWeb使用Datatable進行後端分頁

DjangoWeb使用Datatable進行後端分頁

使用場景:不使用Django的模版語言進行分頁(網上大多數都使用該方式),使用Jquery DataTable.js 外掛進行分頁處理。

本人做的是一個表格監控頁面,該頁面中的table內容每5s重新整理一次。

注意:這種方式非長連線(websocket)模式,長連線模式也有弊端,因網路波動導致,倘若一次連線斷開,後面將無法繼續重新整理資料(不重連的話),且比較吃伺服器頻寬。

故使用Ajax定時重新整理獲取最新資料,兩種方案各有優劣,根據實際場景進行抉擇。

程式碼如下:

1.Html頁面內容(本人用的是Admin.lte的前端框架),

引入Datatable css 和 Js,並建立一個table:

<link rel="stylesheet" href="{% static  '/plugins/bootstrap-datatable/bootstrap-table.css' %}">
<link rel="stylesheet" href="{% static  '/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css' %}">

<table class="table table-bordered table-striped table-hover" id="monitorTable" style="width: 100%">
</table>
<script src="{% static '/bower_components/datatables.net/js/jquery.dataTables.min.js' %}"></script>
<script src="{% static '/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js' %}"></script>

2.頁面載入時本人對錶格內容進行了初始化,下面的兩種方式對錶格都能進行初始化,但是獲取到的var 物件是不一樣的。

這裡一定要注意(分不清楚就是個坑):

以var table1=$("#xxx").Datatable({})

以var table2=$("#xxx").datatable({})

即table1!=table2

這裡要說明下,上面的table1是物件,table2是API物件(請對這句話保持警惕),建議初始化表格時使用table1的方式。

根據官網的描述DataTables的真正威力可以通過使用它提供的API來利用。

關於table2的使用,以後會說明!!!

3.因為同一頁面可能使用多個表格,所以我要多個表格共用的部分提取出來,避免程式碼反覆編寫:

下面的方法定義了3個引數,

lengthMenuParam:table表格左上角的分頁列表“右側”需要顯示哪些內容(這部分可以自定義)

urlParam:table中的資料從哪裡獲取

columnsParam:table中有哪些列內容

這裡要注意下,bProcessing=True這個屬性很重要,這個屬效能很友好的提醒使用者資料正在讀取中,因為讀取伺服器資料是要時間的。

// table初始化方法
function initDataTable(lengthMenuParam, urlParam, columnsParam) {
    return {
            sPaginationType: "full_numbers", //分頁風格,full_number會把所有頁碼顯示出來
            searching: false,//搜尋
            ordering: false,//是否啟用排序
            bProcessing: true, //是否顯示載入
            sAjaxSource: urlParam, //請求資源路徑
            serverSide: true, //開啟伺服器處理模式
            /*
             使用ajax,在服務端處理資料
             sSource:即是"sAjaxSource"
             aoData:要傳遞到服務端的引數
             fnCallback:處理返回資料的回撥函式
             */
            fnServerData: function (sSource, aoData, fnCallback) {
                $.ajax({
                    'type': 'POST',
                    "url": sSource,
                    "dataType": "json",
                    "data": {"aodata": JSON.stringify(aoData)},
                    "success": function (resp) {
                        fnCallback(resp);
                    }
                });
            },
            "oLanguage": {//語言設定
                "sLengthMenu": '<select class="form-control" style="width:150px">'
                + '<option value="10"  selected>每頁10條</option>'
                + '<option value="20">每頁20條</option>'
                + '<option value="50">每頁50條</option>'
                + '<option value="100">每頁100條</option>'
                + '</select>'
+ lengthMenuParam,,
                "sProcessing": "處理中...",
                "sZeroRecords": "沒有匹配結果",
                "sInfo": "顯示第 _START_ 至 _END_ 項結果,共 _TOTAL_ 項",
                "sInfoEmpty": "沒有資料",
                "sInfoFiltered": "(獲取 _MAX_ 項結果)",
                "sInfoPostFix": "",
                "sSearch": "搜尋:",
                "sUrl": "",
                "sEmptyTable": "表中資料為空",
                "sLoadingRecords": "載入中...",
                "sInfoThousands": ",",
                "oPaginate": {
                    "sFirst": "首頁",
                    "sPrevious": "上頁",
                    "sNext": "下頁",
                    "sLast": "末頁"
                },
            },
            "bProcessing": true, //開啟讀取伺服器資料時顯示正在載入中……特別是大資料量的時候,開啟此功能比較好
            "bServerSide": true, //開啟伺服器模式,使用伺服器端處理配置datatable。
            // 注意:sAjaxSource引數也必須被給予為了給datatable原始碼來獲取所需的資料對於每個畫。
            // 這個翻譯有點彆扭。開啟此模式後,你對datatables的每個操作 每頁顯示多少條記錄、下一頁、上一頁、排序(表頭)、搜尋,這些都會傳給伺服器相應的值。
            "columns": columnsParam,
    }
}

定義左側顯示引數:

            var lengthMenuParam =
                '<div class="btn-group">' +
                '<button type="button" class="btn btn-default" data-toggle="modal" data-target="#addResources_modal">新增</button>' +
                '<button type="button" class="btn btn-default selectAllCheck">全選</button>' +
                '<button type="button" class="btn btn-default" id="selectAllDelete">刪除</button>' +
                '</div>';

定義url地址:

var urlParam = "{% url 'Monitor:monitor' %}";

定義列內容:

            var columnsParam = [
                {title: "id", data: "id", sClass: "hidden"},
                {
                    data: null,
                    sWidth: "1%",
                    'render': function (data, type, full, meta) {
                        return meta.row + 1 + meta.settings._iDisplayStart;
                    }
                },
                {
                    title: '<input type="checkbox"  class="selectAllCheck">',
                    sWidth: "1%",
                    data: null,
                    'render': function (data, type, full, meta) {
                        return '<div><input type="checkbox"></div>';
                    }
                },
                {title: "名稱", data: "name"},
                {
                    title: "IP",
                    data: "ip",
                    "render": function (data, type, full, meta) {
                        var strDelete = '<a href="/docker/container?ip=' + data + '" class="text-blue">' + data + '</a>';
                        return strDelete;
                    }
                },
                {title: "作業系統", data: "os"},
                {title: "狀態", data: "status"},
                {title: "建立日期", data: "createTime"},
                {
                    data: null,
                    "render": function (data, type, full, meta) {
                        var strModify = "<button type='button' class='btn btn-warning btn-xs btn-flat modifyResources' data-toggle='modal' data-target='#modifyResources_modal'> <i class='fa fa-pencil'></i>修改</button > ";
                        var strDelete = "<button type='button' class='btn btn-danger btn-xs btn-flat deleteResources' > <i class='fa fa-pencil'></i>刪除</button > ";
                        return strModify + strDelete;
                    }
                },
            ];

上面的列內容中,第1列是隱藏內容,第2列是行序號,第3列check(用來多選的),

第4,6,7,8列是要顯示的資訊,第5列是超連結。

第9列是操作按鈕(根據自己的選擇增加、刪除)。

一般情況下,上述內容已經夠用了。

4.完成表格的初始化:

            $("#monitorTable").DataTable(
                initDataTable(lengthMenuParam, urlParam, columnsParam)
            )
注意,我這裡的datatable分頁使用的是post請求, 因為分頁的時候需要向服務端傳遞很多引數,使用get請求的話,這裡就很難受了。

5.服務端程式碼,返回結果的內容格式是固定的,不要想著去修改:

@csrf_exempt
def monitor(request):
    if request.method == 'GET':
        return render(request, 'monitor/Monitor.html', )
    else:
        dataTable = {}
        aodata = json.loads(request.POST.get("aodata"))
        for item in aodata:
            if item['name'] == "sEcho":
                sEcho = int(item['value'])  # 客戶端傳送的標識
            if item['name'] == "iDisplayStart":
                iDisplayStart = int(item['value'])  # 起始索引
            if item['name'] == "iDisplayLength":
                iDisplayLength = int(item['value'])  # 每頁顯示的行數
        # 獲取最新的時間
        last_time = T_Monitor.objects.order_by('-createTime').first().createTime
        # 根據最新的時間獲取監控資料
        monitor_list = T_Monitor.objects.filter(createTime=last_time).order_by('createTime')
        #monitor_list = T_Monitor.objects.order_by('updateTime').all()
        resultLength = monitor_list.count()
        # 對list進行分頁
        paginator = Paginator(monitor_list, iDisplayLength)
        # 把資料分成10個一頁。
        try:
            monitor_list = paginator.page(iDisplayStart / 10 + 1)
        # 請求頁數錯誤
        except PageNotAnInteger:
            monitor_list = paginator.page(1)
        except EmptyPage:
            monitor_list = paginator.page(paginator.num_pages)
        data=[]
        for item in monitor_list:
            row = {"id": str(item.id),
                   "name": item.name,
                   "ip": item.ip,
                   "os": item.os[0:6],
                   "status": item.status,
                   "createTime": item.createTime.strftime('%Y-%m-%d %H:%M:%S')}
            data.append(row)
        #對最終的資料進行排序
        data = sorted(data, key=lambda item: item['createTime'])
        dataTable['iTotalRecords'] = resultLength  # 資料總條數
        dataTable['sEcho'] = sEcho + 1
        dataTable['iTotalDisplayRecords'] = resultLength  # 顯示的條數
        dataTable['aaData'] = data

        return HttpResponse(json.dumps(dataTable, ensure_ascii=False))

最終的表現結果如下圖:


6.新增定時重新整理table的JS

    <script>

        //重新整理方法
        function runRefresh() {
            var interval = setInterval(refreshMonitor, "5000");
        }
        {#定時器執行方法#}
        function refreshMonitor() {
            var table = $('#monitorTable').DataTable();
            table.ajax.reload(null, false); // 重新整理表格資料,分頁資訊不會重置
        }
        runRefresh();
    </script>

最後強調一點,table資料也是可以通過get請求進行載入的。

但是使用了get方式後,在某頁進行操作再進行上面的JS重新整理時會出現行序號紊亂或者分頁資訊被重置的問題。

這也是我碰到的一個坑。

特此記錄一下。


相關推薦

DjangoWeb使用Datatable進行

使用場景:不使用Django的模版語言進行分頁(網上大多數都使用該方式),使用Jquery DataTable.js 外掛進行分頁處理。本人做的是一個表格監控頁面,該頁面中的table內容每5s重新整理一次。注意:這種方式非長連線(websocket)模式,長連線模式也有弊端

bootstrapTable的數據排序

col 序列 多少 turn ams ots color pan 修改 數據後端分頁排序,其實就是sql語句中oeder by做一些限制。 之前在寫sql語句中的order by是寫死,既然要寫活,就要傳參數到後臺。 之前講到bootstrapTable的queryPara

[轉]Bootstrap table(ssm版)

log 包含 ucc utf-8 get doctype 3.1.1 樣式 poj 原文地址:https://www.cnblogs.com/flyins/p/6752285.html 說明bootstrap table可以前端分頁,也可以後端sql用limit

神器,mybatis pagehelper 在SSM與springboot專案中的使用

mybatis pagehelper想必大家都耳熟能詳了,是java後端用於做分頁查詢時一款非常好用的分頁外掛,同時也被人們稱為mybatis三劍客之一,下面 就給大家講講如何在SSM專案和springboot專案中使用mybatis pagehelper 一、myb

外掛pageBar 使用 springmvc下 hibernate

pagebar外掛,具體說明在 https://blog.csdn.net/xushiyu1996818/article/details/83656610 可以使用下載 controller @RequestMapping(value="/showCanSellProductsA

外掛 pageBar

這個pagebar工具,是我在網上找到兩個分頁外掛,合併修改而成的 下載地址為 https://gitee.com/xushiyu/java_web_tools/tree/master/src/javaweb/pagebar 首先本外掛共分三個部分,PageBar.java 

工具PageHelper

1.引入maven <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</arti

mongo資料庫下和mybatis下的操作

1.Mongo 資料庫下的後端分頁操作 (1)對資料庫查詢資料直接進行分頁分裝: Pageable 是Spring Data庫中定義的一個介面,該介面是所有分頁相關資訊的一個抽象,通過該介面,我們可以得到和分頁相關所有資訊(例如pageNumber、pageSize等),

ssm和Ajax實現

後臺實現程式碼如下: @RequestMapping(value = { "/orderselect" })     public @ResponseBody Map<String, Object> queryorder(HttpServletRequest r

java作為:vue結合datatables

官網:  英文:https://datatables.net/  中文:http://www.datatables.club/ 引入datatables的CSS和JS檔案 css: <link href="statics/css/dat

spring data jpa bootstrap table (詳解)

關於spring data jpa 使用bootstrap table 分頁: 1.bootstrap table  js檔案程式碼: 2.controller中獲取前端分頁的資料: 3.service,需要注意pageabel的引數,這裡沒有使用sort排序方式,所

Bootstrap Table

之前一直用的前端分頁,在資料不是太多的情況下,前端分頁還是很方便的,也可以使用自帶的搜尋等功能,如果資料量比較多的情況就要使用後端

Bootstrap-table服務

idf select bootstarp tor val which zh-cn class lose bootstarp-table服務端分頁 $(‘#test-table‘).bootstrapTable({ //請求方法

用DataTables實現服務器

說明 分頁 scrip ajax query .html detail www. archive 推薦下,H-ui.admin 模版裏面使用了DataTables,而且把常用功能都給實現的很完整了,推薦去參考H-ui的模版源碼參考! 分享幾篇有價值的文章: DataTabl

ASP.NET MVC 結合bootstrap-table-實現服務

bootstrap-table展示資料很好用,但是當資料量很大時,存在效能問題。bootstrap-table需要分頁的功能,需要時就請求資料,而不是一次性載入到客戶端上。bootstrap-table前臺預設時客戶端分頁,此時的分頁已失去了應有的作用。因此使用服務端,話不多說,直接上程式碼 前

使用 Kotlin + Spring Boot 進行開發

Kotlin Kotlin 是一個基於 JVM 的程式語言,它的簡潔、便利早已不言而喻。Kotlin 能夠勝任 Java 做的所有事。目前,我們公司 C 端 的 Android 產品全部採用 Kotlin 編寫。公司的後端專案也可能會使用 Kotlin,所以我給他們做一些 demo 進行演

guns 在伺服器

控制層 1、加資料字典 Page<ReceivingTask> page = new PageFactory<ReceivingTask>().defaultPage(); List<Map<String, Object>>

【問題解決】增加https phpcms 錯誤

https://m.cnbuses.com/m.cnbuses.com/index.php?page=2檢視分頁方法 function pages()中有個pageurl 檢視該方法,發現有類似http字樣沒有https加上試試Ctrl+Shift+F 沒有找不到的東西 替換795行 $url =

###①datatable客戶,全選只能選中一(能力有限,(雖然不是服務),同事-老大都不知道)+ ②【動態新增刪除CheckBox的ID】 JQuery datatables 表頭複選框切換頁面時保持選中的問題

①datatable客戶端分頁,全選只能選中一頁(能力有限,(雖然不是服務端分頁),同事-老大都不知道)。 對於要解決的問題: 【 JQuery datatables 表頭複選框切換頁面時保持選中的問題 】 ==== 這個:https://blog.csdn.net/nihaoqiuli

guns 在客戶

控制層 Page<ReceivingTask> page = new PageFactory<ReceivingTask>().defaultPage(); List<Map<String, Object>