使用Django的JsonResponse更新DataTable工作不正常



我有一个Django应用程序和一个页面,在这个页面上,数据被写入到我正在使用DataTables设置样式的表中。我有一个非常简单的问题,但事实证明它非常复杂。我有一个下拉过滤器,用户可以在其中选择一个选项,单击过滤器,然后ajax请求更新表的html,而无需重新加载页面。问题是,这不会更新DataTable。

我的html:

<table class="table" id="results-table">
<thead>
<tr>
<th scope="col">COL 1</th>
<th scope="col">COL 2</th>
<th scope="col">COL 3</th>
<th scope="col">COL 4</th>
<th scope="col">COL 5</th>
</tr>
</thead>
<tbody class="table_body">
{% include 'results/results_table.html' %}
</tbody>
</table>

results_table.html:

{% for result in result_set %}
<tr class="result-row">
<td>{{ result.col1 }}</td>
<td>{{ result.col2 }}</td>
<td>{{ result.col3 }}</td>
<td>{{ result.col4 }}</td>
<td>{{ result.col5 }}</td>
</tr>
{% endfor %}

javascript:

function filter_results() {
var IDs = [];
var IDSet = $('.id-select');
for (var i = 0; i < IDSet.length; i++) {
var ID = getID($(IDSet[i]));
IDs.push(ID);
}
// var data = [];
// data = $.ajax({
//   url:"filter_results/" + IDs + "/",
//   dataType: "json",
//   async: false,
//   cache: false,
//   data: {},
//   success: function(response) {
//     $('#results-table').html(response);
//     // console.log(response.length);
//     // console.log(typeof response);
//     //
//   }
// }).responseJSON;
var dataTable = $('#results-table').DataTable();
dataTable.clear();
$('.table_body').html('').load("filter_results/" + IDs + "/", function() {
alert("Done");
});
dataTable.draw();
}

和视图:

def filter_results(request, ids):
ids = [int(id) for id in ids.split(',')]
account_set = Account.objects.filter(id__in=ids)
form = ResultsFilterForm()
result_set = Result.objects.filter(account__in=account_set)
context = {
'form': form,
'result_set': result_set
}
return render(request, 'results/results_table.html', context)

实际情况是Ajax正确地更新了我在HTML页面上看到的内容,但没有更新实际的数据表。因此,我可以过滤一个特定的ID,例如,它有2个结果,这将起作用,并在HTML页面上显示这两个结果,而无需重新加载;下一个";当只有两个结果时,页面就没有意义了。

我还尝试更改视图以返回带有JS注释的代码的JSON响应,当我这样做时,我得到了";警告:DataTable在第0行第0列遇到意外参数"0";即使来自Django的数据是JSON格式的正确数据。

真的被困在这里了,谢谢你的帮助。

我找到了一种让它工作的方法。虽然可能不是";最好的";做这件事的方法很简单,所以我希望这能帮助其他人。更改JavaScript如下:

function filter_results() {
$('#results-table').DataTable().destroy();
var IDs = [];
var IDSet = $('.id-select');
for (var i = 0; i < IDSet.length; i++) {
var ID = getID($(IDSet[i]));
IDs.push(ID);
}
$('.table_body').html('').load("filter_results/" + IDs + "/", function() {
$('#results-table').DataTable();
});
}

就是这样。我所需要做的就是销毁filter_results函数开头的旧DataTable,然后重新创建它。但请注意,重新创建是在调用.load()之后执行的函数。如果你不这样写,你会遇到JS在html加载完成之前重新创建DataTable的问题,这是我遇到的一个问题。不过,将该函数嵌套在.load()调用中是一个简单的解决方法。

我知道可能有一种更好的方法可以做到这一点,那就是更新而不是破坏和重新创建DataTable。如果有人知道,请随时将其作为答案发布,但目前这种变通方法对我来说很好!

最新更新