歡迎您光臨本站 註冊首頁

DjangoWeb使用Datatable進行後端分頁的實現

←手機掃碼閱讀     limiyoyo @ 2020-06-10 , reply:0

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

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

注意:這種方式非長連接(websocket)模式,長連接模式也有弊端,因網絡波動導致,倘若一次連接斷開,後面將無法繼續刷新數據(不重連的話),且比較吃服務器帶寬。

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

代碼如下:

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

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

  

 

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": ''      + '每頁10條'      + '每頁20條'      + '每頁50條'      + '每頁100條'      + ''   + 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 =      '' +      '添加' +      '全選' +      '刪除' +      '';

 

定義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: '',       sWidth: "1%",       data: null,       'render': function (data, type, full, meta) {        return '';       }      },      {title: "名稱", data: "name"},      {       title: "IP",       data: "ip",       "render": function (data, type, full, meta) {        var strDelete = '' + data + '';        return strDelete;       }      },      {title: "操作系統", data: "os"},      {title: "狀態", data: "status"},      {title: "創建日期", data: "createTime"},      {       data: null,       "render": function (data, type, full, meta) {        var strModify = "修改";        var strDelete = "刪除";        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

   

 

最後強調一點,table數據也是可以通過get請求進行加載的。

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

這也是我碰到的一個坑。

特此記錄一下。

補充知識:關於python的web框架django和Bootstrap-table的使用

這幾天工作中發現要使用到Bootstrap的分頁,django也有分頁,但是當兩者結合起來時發現,是一個強大的分頁。

第一次接觸這兩者,結合起來時踩了不少坑,因為自己是一個python初學者,以前是學的Java,在公司做的python。

自己在網上找到一些資料,但發現這些資料都說的不明白,所以自己也去看了文檔。

我把自己的代碼貼出來吧。

這個方法是將你的數據跟據你的頁碼,頁面大小,分好頁

  def page(deploy_list ,limit,offset):#查詢分頁,調用此方法需要傳獲取的數據列表,頁面大小,頁碼    # 取出該表所有數據   try:    paginator = Paginator(deploy_list, limit) # 每頁顯示10條數據   except Exception:    print "error"   page = int(int(offset) / int(limit) + 1)   data=paginator.page(page)   response_data = {'total': deploy_list.count(), 'rows': []} # 必須帶有rows和total這2個key,total表示總頁數,rows表示每行的內容,這兩個是Bootstrap需要的   return {"data":data,"response_data":response_data}

 

調用上述方法時將自己需要的數據獲取到

  def list(request):   J_data=page(modename.object.all().values(),request.GET.get("limit"),request.GET.get("offset"))#modelname,這個是你需要查詢的model,modename.object.all().values(),這個可以根據自己的查詢條件去更改,例如:modename.object.filter(username=requset.GET.get("username")).values()   for asset in J_data:    J_data['response_data']['youmodel ziduan '].append({     "asset_id":asset["asset_id"],"asset_id":asset["asset_id"],  })   return HttpResponse(json.dumps(J_data["response_data"])) # 需要json處理下數據格式

 

前臺代碼百度很多,可以自己去寫 ,這裡就不再陳述


   


[limiyoyo ] DjangoWeb使用Datatable進行後端分頁的實現已經有265次圍觀

http://coctec.com/docs/python/shhow-post-237779.html