我有一个带有 d3.select('svg').on('click', (d, i, nodes) => {
let coor = d3.mouse(nodes[i]);
console.log(coor[0]);
});
模型的Django项目。此模型是分析列表。它有一个Analytic
和一个ForeignKeyField
字段。最终目标是让用户转到一个URL,在该URL中他们可以查看DataTable中的Analytics列表,创建新的分析,编辑分析和删除分析。使用本教程: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来序列化我的ManyToMany
模型。这在一定程度上起作用:JSON输出看起来不错,结果显示在我的DataTable中。但是,在进行Ajax调用时,数据仍未更新。此外,DataTables并不真正允许内联按钮进行编辑/删除,这就是为什么必须首先在HTML中手动编写这些按钮。
问题:当执行Ajax CRUD操作时,如何强制从HTML / DOM获取的DataTable更新其数据而不刷新页面?
views.py:
Analytic
urls.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)
analytic_list.html:
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'),
partial_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 %}
的analytics.js:
{% 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 %}
答案 0 :(得分:0)
看起来你的表更新正在使用它:
$("#analytic-table tbody").html(data.html_analytic_list);
您需要Datatables API来更新Datatables数据。由于您直接更新HTML数据表,因此不了解更新。一种选择是使用rows().invalidate()之类的东西让Datatables在使用HTML方法更新后更新其数据缓存。
但更好的选择是将rows.add()用于多行,或row.add()用于单行。
由于您的数据中看起来有tr
元素,因此您可以分别对一行或多行使用此类内容:
table.row.add($(data.html_analytic_list)).get(1)).draw();
table.rows.add($(data.html_analytic_list))).draw();
答案 1 :(得分:0)
我将假设您正在谈论JQuery Datatables。您太亲密了,只差了一点!您需要销毁并重新初始化表,而无需使用.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;
};
工作愉快,祝你好运!答案较晚,但也许会对某人有所帮助。