問題背景
在筆者文Django - 如何實(shí)現(xiàn)用戶進(jìn)行數(shù)據(jù)查詢(表格)的功能遵馆?datatable - client processing談到在使用datatable使用client processing的時(shí)候庆捺,存在以下兩個(gè)問題:
- 數(shù)據(jù)庫(kù)太大的時(shí)候,比如有百萬(wàn)級(jí)別數(shù)據(jù)的時(shí)候闷愤, 一次性發(fā)送json數(shù)據(jù)的速度就有待考證。
- 前端一次性獲得數(shù)據(jù)之后件余,再分頁(yè)的時(shí)候讥脐,都是上次瀏覽的時(shí)候緩存的數(shù)據(jù)處理的,那么在用戶眼前的數(shù)據(jù)可能并不是服務(wù)器中實(shí)時(shí)的數(shù)據(jù)
本文將講述啼器,如何通過使用datatable插件的自帶能力 server processing來(lái)解決這兩個(gè)問題旬渠。
HTML實(shí)現(xiàn)
<div class="col-md-12">
<table class="table table-striped table-bordered table-hover table-checkable order-column" id="sample_1">
<thead>
<tr>
<th>
<label class="mt-checkbox mt-checkbox-single mt-checkbox-outline">
<input type="checkbox" class="group-checkable" data-set="#sample_1 .checkboxes"/>
<span></span>
</label>
</th>
<th> 書名</th>
<th> 出版社</th>
<th> 借閱次數(shù)</th>
<th> 數(shù)量</th>
<th> 作者</th>
<th> 狀態(tài)</th>
<th> ISBN</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
HTML實(shí)現(xiàn)和使用client processing的方式保持一致,并沒有什么不同端壳。
js 實(shí)現(xiàn)
$(document).ready(function() {
$("#sample_1").dataTable(
{
searching : false,
destroy : true,
"processing" : true,
"serverSide" : true,
"ajax": {
"url": "book/query/",
"type": "POST",
"data": function(d){
return $.extend( {}, d, {
"author" : document.getElementById('id_author').value,
"press" : document.getElementById('press').value,
"isbn" : document.getElementById('isbn').value,
"name" : document.getElementById('book').value,
"status" : document.getElementById('status').value
});
}
},
columns: [
{ },
{ data: 'name' },
{ data: 'press' },
{ data: 'lendCount' },
{ data: 'acount' },
{ data: 'author' },
{ data: 'status' },
{ data: 'isbn' }
],
'columnDefs': [{
'targets': 0,
'searchable': false,
'orderable': false,
'className': 'select-checkbox',
'render': function (data, type, full, meta){
return '<label class="mt-checkbox mt-checkbox-single mt-checkbox-outline"><input type="checkbox" class="checkboxes" value="1"/><span></span></label>'
}
}],
}
);
});
和clinet processing相比告丢, 在需要使用datatable的server processing的特性的時(shí)候, 有以下注意點(diǎn):
- 將 processing 和 serverSide 選項(xiàng)置為 true
- 說明ajax:type為 POST
- 指定處理該ajax請(qǐng)求的url损谦,如本例中的"url":"book/query", 該url需要在Django后臺(tái)的urls.py中注冊(cè)
Django實(shí)現(xiàn)
def post(self, request):
if request.method == "POST":
dumpRequest(request)
objects = Book.objects.all()
recordsTotal = objects.count()
recordsFiltered = recordsTotal
start = int(request.POST['start'])
length = int(request.POST['length'])
draw = int(request.POST['draw'])
objects = objects[start:(start + length)]
dic = [obj.as_dict() for obj in objects]
resp = {
'draw': draw,
'recordsTotal': recordsTotal,
'recordsFiltered': recordsFiltered,
'data': dic,
}
return HttpResponse(json.dumps(resp), content_type="application/json")
在使用datatable的server processing的時(shí)候岖免, 后端返回給前端的數(shù)據(jù)需要以jason格式返回, 而且返回的數(shù)據(jù)格式也有要求照捡。 如果說返回的數(shù)據(jù)格式不匹配颅湘,datatable插件會(huì)彈框提示出錯(cuò)信息。
在本例子中栗精,我們的返回信息包括以下內(nèi)容
- draw 這一項(xiàng)將獲取到的ajax json request中的數(shù)據(jù)闯参,轉(zhuǎn)成int返回
- recordsTotal 所有記錄的條數(shù)
- recordsFiltered 過濾之后的記錄的條數(shù)
-
data 返回的表格的內(nèi)容數(shù)據(jù)
在之前ajax request中瞻鹏,還有一個(gè)關(guān)于data域的內(nèi)容也值得一提
"data": function(d){
return $.extend( {}, d, {
"author" : document.getElementById('id_author').value,
"press" : document.getElementById('press').value,
"isbn" : document.getElementById('isbn').value,
"name" : document.getElementById('book').value,
"status" : document.getElementById('status').value
});
}
},
這段代碼所起的作用是說,在ajax request的內(nèi)容里面不僅僅包括datatables生成的內(nèi)容鹿寨, 還包含DOM里面id_author/press/isbn/book/status這5個(gè)input控件的值新博。這樣Django后臺(tái)可以根據(jù)這幾個(gè)值去做數(shù)據(jù)過濾。
我們只需將form表單的submit做如下實(shí)現(xiàn)脚草,即可在用戶點(diǎn)擊form表單提交按鈕的時(shí)候赫悄, 進(jìn)行數(shù)據(jù)查詢呢
$("form").submit(function(e){
e.preventDefault();
table = $("#sample_1").DataTable();
table.ajax.reload();
});
下一篇文章,我們將來(lái)講述在server processing的情況下馏慨,如何實(shí)現(xiàn)數(shù)據(jù)過濾和排序
參考
- 官方關(guān)于server processing make post request的說明https://www.datatables.net/examples/server_side/post.html