简体   繁体   English

使用来自 Django 的 JsonResponse 更新数据表无法正常工作

[英]Update DataTable with JsonResponse from Django not working properly

I have a Django application and a page where data is written to a table that I am styling using DataTables.我有一个 Django 应用程序和一个页面,其中数据被写入我使用 DataTables 样式化的表中。 I have a very simple problem that has proven remarkably complicated to figure out.我有一个非常简单的问题,但事实证明,要弄清楚它非常复杂。 I have a dropdown filter where users can select an option, click filter, and then an ajax request updates the html of the table without reloading the page.我有一个下拉过滤器,用户可以在其中选择一个选项,单击过滤器,然后 ajax 请求更新表的 html,而无需重新加载页面。 Problem is, this does not update the DataTable.问题是,这不会更新 DataTable。

My html:我的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:结果表.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: 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();
  }

And views:和意见:

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)

What is happening is that the Ajax is correctly updating what I see on the HTML page, but it is not updating the actual data table.发生的事情是 Ajax 正确更新了我在 HTML 页面上看到的内容,但没有更新实际的数据表。 So I can filter for a particular ID, for instance, which has 2 results and this will work and show me the two results on the HTML page without reloading it.所以我可以过滤一个特定的 ID,例如,它有 2 个结果,这将起作用并在 HTML 页面上向我显示两个结果,而无需重新加载它。 However, the DataTable still contains the rest of the results so there is still like a "next" page which makes no sense when there are only 2 results.但是,DataTable 仍然包含其余的结果,因此当只有 2 个结果时,仍然像“下一个”页面一样没有意义。

I also tried changing the view to return a JSON response with the code that is commented out of the JS and when I did that I got "Warning: DataTable encountered unexpected parameter '0' at row 0 column 0" even though the data coming from Django was the correct data in JSON form.我还尝试更改视图以返回带有从 JS 中注释掉的代码的 JSON 响应,当我这样做时,即使数据来自Django 是 JSON 格式的正确数据。

Really stuck here, appreciate the help.真的卡在这里,感谢帮助。

I figured out a way to make it work.我想出了一个办法让它发挥作用。 Though maybe not the "best" way to do this, it is simple so I hope this helps someone else.虽然可能不是做到这一点的“最佳”方式,但它很简单,所以我希望这对其他人有所帮助。 Change JavaScript as follows:更改 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();
    });
  }

That was it.就是这样。 All I needed to do was destroy the old DataTable at the beginning of the filter_results function and then re-create it.我需要做的就是在 filter_results 函数的开头销毁旧的 DataTable,然后重新创建它。 Note however that the recreation is the function to execute after the call to .load() .但是请注意,重新创建是在调用.load()之后执行的函数。 If you don't write it like this you will have an issue with JS recreating the DataTable before the the html is finished loading, which is a problem I encountered.如果你不这样写,那么在html加载完成之前JS重新创建DataTable就会出现问题,这是我遇到的一个问题。 Nesting that function inside the .load() call is an easy workaround though.将该函数嵌套在.load()调用中是一个简单的解决方法。

I know there is probably a better way to do this, one that involves updating rather than destroying and recreating the DataTable.我知道可能有更好的方法来做到这一点,它涉及更新而不是破坏和重新创建 DataTable。 If somebody knows of it feel free to post it as an answer but for now this workaround is good for me!如果有人知道它,请随时将其发布为答案,但现在这种解决方法对我有好处!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM