javascript - DataTables 刷新 Django Ajax 上的 CRUD 操作数据

标签 javascript jquery python django datatables

我有一个带有分析模型的 Django 项目。该模型是一个分析列表。它有一个 ForeignKeyField 和一个 ManyToMany 字段。最终目标是让用户转到一个 URL,他们可以在其中查看数据表中的分析列表、创建新分析、编辑分析和删除分析。使用本教程:https://simpleisbetterthancomplex.com/tutorial/2016/11/15/how-to-implement-a-crud-using-ajax-and-json.html ,我在常规 Bootstrap HTML 表(即不在 DataTable 中)实现了所有这些目标。

当我尝试将 DataTable 引入混合中时,我发现我的 DataTable 是从 HTML/DOM 源中提取的,因此除非刷新页面,否则它不会更新。因此,我随后意识到,我需要将 DataTable 配置为最初从 HTML/DOM 拉取,然后从 AJAX 拉取,或者我需要最初使用 Ajax 作为源。

事实证明,常规 Django 不能很好地序列化 ManyToMany 字段,因此我选择使用 DRF 来序列化我的 Analytic 模型。这在一定程度上有效:JSON 输出看起来不错,结果显示在我的数据表中。但是,当进行 Ajax 调用时,数据仍然没有更新。此外,DataTables 并不真正允许使用内联按钮进行编辑/删除,这就是为什么首先需要手动将这些按钮写入 HTML 的原因。

问题:当执行 Ajax CRUD 操作时,如何强制从 HTML/DOM 获取的 DataTable 更新其数据而不刷新页面?

views.py:

def analytic_list(request):
    analytics = Analytic.objects.all().select_related('analyticCategory').prefetch_related('dataSources')
    return render(request, 'analytics/analytic_list.html', {'analytics':analytics})

def save_analytic_form(request, form, template_name):
    data = dict()
    if request.method == 'POST':
        if form.is_valid():
            form.save()
            data['form_is_valid'] = True
            analytics = Analytic.objects.all()
            data['html_analytic_list'] = render_to_string('analytics/includes/partial_analytic_list.html', {
                'analytics': analytics
            })
        else:
            data['form_is_valid'] = False
    context = {'form': form}
    data['html_form'] = render_to_string(template_name, context, request=request)
    return JsonResponse(data)


def analytic_create(request):
    if request.method == 'POST':
        form = AnalyticForm(request.POST)
    else:
        form = AnalyticForm()
    return save_analytic_form(request, form, 'analytics/includes/partial_analytic_create.html')


def analytic_update(request, pk):
    analytic = get_object_or_404(Analytic, pk=pk)
    if request.method == 'POST':
        form = AnalyticForm(request.POST, instance=analytic)
    else:
        form = AnalyticForm(instance=analytic)
    return save_analytic_form(request, form, 'analytics/includes/partial_analytic_update.html')

def analytic_delete(request, pk):
    analytic = get_object_or_404(Analytic, pk=pk)
    data = dict()
    if request.method == 'POST':
        analytic.delete()
        data['form_is_valid'] = True  # This is just to play along with the existing code
        analytics = Analytic.objects.all()
        data['html_analytic_list'] = render_to_string('analytics/includes/partial_analytic_list.html', {
            'analytics': analytics
        })
    else:
        context = {'analytic': analytic}
        data['html_form'] = render_to_string('analytics/includes/partial_analytic_delete.html',
            context,
            request=request,
        )
    return JsonResponse(data)

url.py:

url(r'^dataanalytics/analytics/$', views.analytic_list, name='analytic_list'),
    url(r'^dataanalytics/analytics/create/$', views.analytic_create, name='analytic_create'),
    url(r'^dataanalytics/analytics/(?P<pk>\d+)/update/$', views.analytic_update, name='analytic_update'),
    url(r'^dataanalytics/analytics/(?P<pk>\d+)/delete/$', views.analytic_delete, name='analytic_delete'),

analytic_list.html:

{% block content %}
<!-- BUTTON TO TRIGGER THE ACTION -->
  <p>
  <button type="button"
          class="btn btn-primary js-create-analytic"
          data-url="{% url 'analytic_create' %}">
    <span class="fa fa-plus"></span>
    New analytic
  </button>
</p>

  <table class="table table-hover table-sm display responsive" width="100%" cellspacing="0" id="analytic-table">
    <thead>
      <tr>
        <th class="all align-top">#</th>
        <th class="all align-top">Name</th>
        <th class="all align-top">Description</th>
        <th class="all align-top">Category</th>
        <th class="all align-top">Type</th>
        <th class="all align-top">Format</th>
        <th class="all align-top">Data Source(s)</th>
        <th class="all align-top"></th>
        <th class="none">Created By</th>
        <th class="none">Created Date</th>
        <th class="none">Modified By</th>
        <th class="none">Modified Date</th>
      </tr>
    </thead>
    <!-- <tbody>
      {% include 'analytics/includes/partial_analytic_list.html' %}
    </tbody> -->
  </table>

<!-- THE MODAL WE WILL BE USING -->
  <div class="modal fade" id="modal-analytic">
  <div class="modal-dialog">
    <div class="modal-content">
    </div>
  </div>
{% endblock %}

partial_analytic_list.html:

{% for analytic in analytics %}
  <tr>
    <td>{{ analytic.id }}</td>
    <td>{{ analytic.analytic }}</td>
    <td>{{ analytic.analyticDescription }}</td>
    <td>{{ analytic.analyticCategory }}</td>
    <td>{{ analytic.analyticType }}</td>
    <td>{{ analytic.analyticFormat }}</td>
    <td>
      {% for data_source in analytic.dataSources.all %}
        {{ data_source }}
      {% endfor %}
    </td>
    <td>
      <button type="button"
              class="btn btn-warning btn-sm js-update-analytic"
              data-url="{% url 'analytic_update' analytic.id %}">
        <span class="fa fa-pencil-alt"></span>
      </button>
      <button type="button"
              class="btn btn-danger btn-sm js-delete-analytic"
              data-url="{% url 'analytic_delete' analytic.id %}">
        <span class="fa fa-trash-alt"></span>
      </button>
    </td>
    <td>{{ analytic.createdBy }}</td>
    <td>{{ analytic.createdDateTime }}</td>
    <td>{{ analytic.modifiedBy }}</td>
    <td>{{ analytic.modifiedDateTime }}</td>
  </tr>
{% empty %}
  <tr>
    <td colspan="7" class="text-center bg-warning">No analytic</td>
  </tr>
{% endfor %}

analytics.js:

$(function () {

  /* Functions */

  var loadForm = function () {
    var btn = $(this);
    $.ajax({
      url: btn.attr("data-url"),
      type: 'get',
      dataType: 'json',
      beforeSend: function () {
        $("#modal-analytic").modal("show");
      },
      success: function (data) {
        $("#modal-analytic .modal-content").html(data.html_form);
      }
    });
  };

  var saveForm = function () {
    var form = $(this);
    $.ajax({
      url: form.attr("action"),
      data: form.serialize(),
      type: form.attr("method"),
      dataType: 'json',
      success: function (data) {
        if (data.form_is_valid) {
          $("#analytic-table tbody").html(data.html_analytic_list);
          $("#modal-analytic").modal("hide");
        }
        else {
          $("#modal-analytic .modal-content").html(data.html_form);
        }
      }
    });
    return false;
  };


  /* Binding */

  // Create analytic
  $(".js-create-analytic").click(loadForm);
  $("#modal-analytic").on("submit", ".js-analytic-create-form", saveForm);

  // Update analytic
  $("#analytic-table").on("click", ".js-update-analytic", loadForm);
  $("#modal-analytic").on("submit", ".js-analytic-update-form", saveForm);

  // Delete analytic
  $("#analytic-table").on("click", ".js-delete-analytic", loadForm);
  $("#modal-analytic").on("submit", ".js-analytic-delete-form", saveForm);


  var table = $('#analytic-table').DataTable(
    {
    });

});

最佳答案

我假设您正在谈论 JQuery 数据表。你已经很接近了,只是缺少一些东西!您需要销毁并重新初始化表格,无需使用.draw()。按照此处所示进行操作:

Ajax :

  var saveForm = function () {
    var form = $(this);
    $.ajax({
      url: form.attr("action"),
      data: form.serialize(),
      type: form.attr("method"),
      dataType: 'json',
      success: function (data) {
        if (data.form_is_valid) {
          $("#modal-analytic").modal("hide"); //hide it first if you want
          $("#analytic-table").DataTable().destroy(); //this will flush DT's cache
          $("#analytic-table tbody").html(data.html_analytic_list); // replace the html
          $("#analytic-table").DataTable(); // re-initialize the DataTable
        }
        else {
          $("#modal-analytic .modal-content").html(data.html_form);
        }
      }
    });
    return false;
  };

干得好,祝你好运!迟到的回答,但也许会对某人有所帮助。

关于javascript - DataTables 刷新 Django Ajax 上的 CRUD 操作数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48648408/

相关文章:

javascript - JS 中的分页

python - 更改蒸馏器记录器

python - 有没有办法在 nginx 上使用 django 上传非常大的文件?

javascript - 用javascript数组填充html

javascript - 使用类似于 adsense 的异步 javascript 显示远程页面

javascript - 如何检查 div 是否对用户可见?

javascript - 仅在一个菜单中禁用数据自动关闭下拉基础

javascript - YouTube Player API - 播放列表如何获取当前视频播放

javascript - 使用 Passport.js 注册用户还是手动创建用户?

python - 删除所有斜杠和反斜杠