首页 > 解决方案 > Tabulator PUT 通过 Ajax 到 Django REST 端点 - 将表减少到最后编辑的记录

问题描述

我正在使用带有 Django 的 Tabulator 来编辑模型。在对单元格进行任何更改后,我使用 setData 对使用 Django REST 框架创建的 REST 端点进行 Ajax 调用。数据库更新正常。问题是来自服务器的响应仅包含已更新的单个记录,这使得 Tabulator 数据减少到仅该记录。

我的问题是,我怎样才能让 Tabulator 忽略响应,或者在编辑后保留数据?

我对这些东西(Django 和尤其是 JavaScript)很陌生,所以如果我错过了一些基本的东西,我深表歉意。

我的制表符代码如下。

  1. 这是根据此处function getCookie的 Django 文档中的说明生成 CSRF_TOKEN 。然后将其包含在as 中。header'X-CSRFTOKEN': CSRF_TOKEN
  2. 该变量ajaxConfigPut用于将方法设置为 PUT 并包括上面提到的 CSRF_TOKEN。然后table.setData在 ( ) 的调用中使用它table.setData(updateurl, updateData, ajaxConfigPut);
  3. 最后的函数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>

这是编辑前的表格截图: 编辑前的表格

这是编辑顶行后的屏幕截图(将“Mabel”更改为“Jemima”): 编辑后的屏幕截图

这是控制台日志: 控制台日志

我尝试修改来自端点的响应,以便返回数据库中的所有记录,但问题是它不包括编辑,因此 Tabulator 表数据被覆盖。这是我在 Django views.py 中使用的代码。也许有办法返回已更改的数据? 视图.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__'

有人可以指出我正确的方向吗?

标签: djangotabulator

解决方案


您使用的所有 MixinsCustomerUpdateAPIView都没有一个名为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/ 在那里您将看到您正在使用的类的所有方法,以更好地了解您的请求流程。


推荐阅读