Tabulator PUT 通过 Ajax 到 Django REST 端点 - 减少 Table 到最后编辑的记录
Tabulator PUT via Ajax to Django REST Endpoint - Reduces Table to Last Edited Record
我正在使用 Tabulator 和 Django 来编辑模型。在对单元格进行任何更改后,我使用 setData 对使用 Django REST Framework 创建的 REST 端点进行 Ajax 调用。数据库更新正常。问题是来自服务器的响应仅包含更新的单个记录,这使得制表符数据减少到仅该记录。
我的问题是,如何让 Tabulator 忽略响应,或者让数据在编辑后保持独立?
我对这些东西很陌生(包括 Django,尤其是 JavaScript),如果我错过了一些基本的东西,我深表歉意。
我的制表符代码如下。
function getCookie
是根据 Django 文档 here 中的说明生成一个 CSRF_TOKEN。然后将其作为 'X-CSRFTOKEN': CSRF_TOKEN
. 包含在 header
中
- 变量
ajaxConfigPut
用于将方法设置为PUT 并包括如上所述的CSRF_TOKEN。然后在稍后 (table.setData(updateurl, updateData, ajaxConfigPut);
) 的 table.setData
调用中使用它。
- 最后的函数
ajaxResponse
只是检查响应是否是一个数组(因为 Tabulator 需要一个适合 GET 的数组,但 PUT 响应只是一个单一的 {} 对象。所以此函数强制将 PUT 响应放入由一个对象 [{}]
. 组成的数组中
<div id="example-table"></div>
<script type="text/javascript">
// get CSRF token
// https://docs.djangoproject.com/en/dev/ref/csrf/#acquiring-the-token-if-csrf-use-sessions-and-csrf-cookie-httponly-are-false
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var CSRF_TOKEN = getCookie('csrftoken');
// set variable to customise ajaxConfig for use in the setData call
var ajaxConfigPut = {
method:"PUT", //set request type to Position
headers: {
// "Content-type": 'application/json; charset=utf-8', //set specific content type
'X-CSRFTOKEN': CSRF_TOKEN,
},
};
//create Tabulator on DOM element with id "example-table"
var table = new Tabulator("#example-table", {
ajaxURL:"{% url 'cust_listapi' %}", // reverse pick up the url since in a django template (?)
height:205, // set height of table (in CSS or here), this enables the Virtual DOM and improves render speed dramatically (can be any valid css height value)
layout:"fitColumns", //fit columns to width of table (optional)
columns:[ //Define Table Columns
{title:"Name", field:"name", width:150, editor:true},
{title:"Age", field:"age", hozAlign:"center",editor:true},
{title:"Age_Bar", field:"age", hozAlign:"left", formatter:"progress"},
{title:"Customer Status", field:"is_customer", hozAlign:"left"},
// {title:"Favourite Color", field:"col"},
// {title:"Date Of Birth", field:"dob", sorter:"date", hozAlign:"center"},
],
// see http://tabulator.info/docs/4.6/components#component-cell
cellEdited:function(cell){ //trigger an alert message when the row is clicked
console.log("Cell edited in row " + cell.getData().id
+ " and column " + cell.getField()
+ " from " + cell.getOldValue() + " to "
+ cell.getValue()
+ ". The row pk=" + cell.getData().id
);
console.log(cell.getData());
var updateurl = "{% url 'cust_listapi' %}" + cell.getData().id + "/"
console.log('URL is: ' + updateurl)
// Create variable from full row data but drop the id;
console.log('About to create updateData')
var updateData = {};
updateData[cell.getField()] = cell.getValue();
console.log(updateData);
console.log('About to setData');
table.setData(updateurl, updateData, ajaxConfigPut);
console.log('Finished setData');
//cell.restoreOldValue();
},
ajaxResponse:function(url, params, response){
console.log('Beginning ajaxResponse')
console.log('The type is:', typeof(response));
console.log(Array.isArray(response))
console.log(response)
result = response;
if(Array.isArray(response) === false){
result = [response];
};
return result;
}
});
</script>
这是 table 编辑前的截图:
Table Before Editing
这是编辑第一行后的屏幕截图(将 'Mabel' 更改为 'Jemima'):
Screenshot after editing
控制台日志如下:
Console Log
我尝试修改端点的响应,以便对数据库中的所有记录进行 returned,但问题是它不包括编辑,因此制表符 table数据被覆盖。这是我在 Django views.py 中使用的代码。也许有办法 return 已更改的数据?
views.py
from rest_framework import generics, mixins
from apps.app_mymodel.models import Customer
from .serializers import CustomerSerializer
class CustomerListAPIView(generics.ListAPIView):
serializer_class = CustomerSerializer
queryset = Customer.objects.all()
class CustomerUpdateAPIView(generics.GenericAPIView,
mixins.ListModelMixin,
mixins.UpdateModelMixin):
serializer_class = CustomerSerializer
queryset = Customer.objects.all()
# Override the put function here to return all records
def put(self, request, *args, **kwargs):
# return self.update(request, *args, **kwargs)
return self.list(request, *args, **kwargs)
这是序列化程序:
serializers.py
from rest_framework import serializers
from apps.app_mymodel.models import Customer
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
fields = '__all__'
有人能给我指出正确的方向吗?
您的 CustomerUpdateAPIView
使用的 None 个 Mixin 有一个名为 put
的方法。我不认为该函数被调用。相反,您可以尝试覆盖视图集的 update
方法。它可能看起来像这样:
def update(self, request, *args, **kwargs):
obj = super().update(request, *args, **kwargs) # performs the update operation
return self.list(request, *args, **kwargs)
您可以查看此 URL 以了解您正在使用的 类:http://www.cdrf.co/
在那里您将看到您正在使用的 类 的所有方法,以更好地理解您的请求流程。
我正在使用 Tabulator 和 Django 来编辑模型。在对单元格进行任何更改后,我使用 setData 对使用 Django REST Framework 创建的 REST 端点进行 Ajax 调用。数据库更新正常。问题是来自服务器的响应仅包含更新的单个记录,这使得制表符数据减少到仅该记录。
我的问题是,如何让 Tabulator 忽略响应,或者让数据在编辑后保持独立?
我对这些东西很陌生(包括 Django,尤其是 JavaScript),如果我错过了一些基本的东西,我深表歉意。
我的制表符代码如下。
function getCookie
是根据 Django 文档 here 中的说明生成一个 CSRF_TOKEN。然后将其作为'X-CSRFTOKEN': CSRF_TOKEN
. 包含在 - 变量
ajaxConfigPut
用于将方法设置为PUT 并包括如上所述的CSRF_TOKEN。然后在稍后 (table.setData(updateurl, updateData, ajaxConfigPut);
) 的table.setData
调用中使用它。 - 最后的函数
ajaxResponse
只是检查响应是否是一个数组(因为 Tabulator 需要一个适合 GET 的数组,但 PUT 响应只是一个单一的 {} 对象。所以此函数强制将 PUT 响应放入由一个对象[{}]
. 组成的数组中
header
中
<div id="example-table"></div>
<script type="text/javascript">
// get CSRF token
// https://docs.djangoproject.com/en/dev/ref/csrf/#acquiring-the-token-if-csrf-use-sessions-and-csrf-cookie-httponly-are-false
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var CSRF_TOKEN = getCookie('csrftoken');
// set variable to customise ajaxConfig for use in the setData call
var ajaxConfigPut = {
method:"PUT", //set request type to Position
headers: {
// "Content-type": 'application/json; charset=utf-8', //set specific content type
'X-CSRFTOKEN': CSRF_TOKEN,
},
};
//create Tabulator on DOM element with id "example-table"
var table = new Tabulator("#example-table", {
ajaxURL:"{% url 'cust_listapi' %}", // reverse pick up the url since in a django template (?)
height:205, // set height of table (in CSS or here), this enables the Virtual DOM and improves render speed dramatically (can be any valid css height value)
layout:"fitColumns", //fit columns to width of table (optional)
columns:[ //Define Table Columns
{title:"Name", field:"name", width:150, editor:true},
{title:"Age", field:"age", hozAlign:"center",editor:true},
{title:"Age_Bar", field:"age", hozAlign:"left", formatter:"progress"},
{title:"Customer Status", field:"is_customer", hozAlign:"left"},
// {title:"Favourite Color", field:"col"},
// {title:"Date Of Birth", field:"dob", sorter:"date", hozAlign:"center"},
],
// see http://tabulator.info/docs/4.6/components#component-cell
cellEdited:function(cell){ //trigger an alert message when the row is clicked
console.log("Cell edited in row " + cell.getData().id
+ " and column " + cell.getField()
+ " from " + cell.getOldValue() + " to "
+ cell.getValue()
+ ". The row pk=" + cell.getData().id
);
console.log(cell.getData());
var updateurl = "{% url 'cust_listapi' %}" + cell.getData().id + "/"
console.log('URL is: ' + updateurl)
// Create variable from full row data but drop the id;
console.log('About to create updateData')
var updateData = {};
updateData[cell.getField()] = cell.getValue();
console.log(updateData);
console.log('About to setData');
table.setData(updateurl, updateData, ajaxConfigPut);
console.log('Finished setData');
//cell.restoreOldValue();
},
ajaxResponse:function(url, params, response){
console.log('Beginning ajaxResponse')
console.log('The type is:', typeof(response));
console.log(Array.isArray(response))
console.log(response)
result = response;
if(Array.isArray(response) === false){
result = [response];
};
return result;
}
});
</script>
这是 table 编辑前的截图: Table Before Editing
这是编辑第一行后的屏幕截图(将 'Mabel' 更改为 'Jemima'): Screenshot after editing
控制台日志如下: Console Log
我尝试修改端点的响应,以便对数据库中的所有记录进行 returned,但问题是它不包括编辑,因此制表符 table数据被覆盖。这是我在 Django views.py 中使用的代码。也许有办法 return 已更改的数据? views.py
from rest_framework import generics, mixins
from apps.app_mymodel.models import Customer
from .serializers import CustomerSerializer
class CustomerListAPIView(generics.ListAPIView):
serializer_class = CustomerSerializer
queryset = Customer.objects.all()
class CustomerUpdateAPIView(generics.GenericAPIView,
mixins.ListModelMixin,
mixins.UpdateModelMixin):
serializer_class = CustomerSerializer
queryset = Customer.objects.all()
# Override the put function here to return all records
def put(self, request, *args, **kwargs):
# return self.update(request, *args, **kwargs)
return self.list(request, *args, **kwargs)
这是序列化程序: serializers.py
from rest_framework import serializers
from apps.app_mymodel.models import Customer
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
fields = '__all__'
有人能给我指出正确的方向吗?
CustomerUpdateAPIView
使用的 None 个 Mixin 有一个名为 put
的方法。我不认为该函数被调用。相反,您可以尝试覆盖视图集的 update
方法。它可能看起来像这样:
def update(self, request, *args, **kwargs):
obj = super().update(request, *args, **kwargs) # performs the update operation
return self.list(request, *args, **kwargs)
您可以查看此 URL 以了解您正在使用的 类:http://www.cdrf.co/ 在那里您将看到您正在使用的 类 的所有方法,以更好地理解您的请求流程。