PUT Tabulator через Ajax до Django Конечная точка REST - уменьшает таблицу до последней отредактированной записи - PullRequest
0 голосов
/ 29 апреля 2020

Я использую Tabulator с Django для редактирования модели. После любого изменения ячейки я использую setData, чтобы сделать Ajax вызов конечной точки REST, созданной с использованием Django REST Framework. Обновление базы в порядке. Проблема в том, что ответ от сервера содержит только одну запись, которая была обновлена, и это приводит к уменьшению данных Табулятора только до этой записи.

У меня вопрос: как я могу заставить Tabulator игнорировать ответ или иначе оставить данные в покое после редактирования?

Я довольно новичок в этом (оба Django и особенно JavaScript), поэтому прошу прощения, если я что-то пропустил, если c.

Код моего табулятора приведен ниже.

  1. function getCookie - генерировать CSRF_TOKEN согласно инструкциям в Django документации здесь . Затем он включается в 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. Может быть, есть способ вернуть данные, которые были изменены? views.py

* 104 3 *

Вот сериализатор: serializers.py

from rest_framework import serializers
from apps.app_mymodel.models import Customer

class CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer
        fields = '__all__'

Может кто-нибудь указать мне правильное направление?

1 Ответ

0 голосов
/ 29 апреля 2020

Ни один из Mixins, используемых вашим CustomerUpdateAPIView, не имеет метода с именем 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/ Там вы увидите все методы классов, которые вы используете используя, чтобы лучше понять поток вашего запроса.

...