Когда проект ориентирован на данные, потребность в красивой визуализации неоспорима. Kendo-ui - это специализированный интерфейсный фреймворк для этой цели. С его помощью мы можем создавать интерактивные и настраиваемые таблицы, графики и диаграммы. Сегодня я расскажу кое-что о наиболее широко используемых сетках компонентов kendo-ui и правильном способе соединения с серверной частью.

Самый наивный способ интегрировать сетку кендо-пользовательский интерфейс в ваш проект - это очень просто. Просто визуализируйте таблицу, которую вы обычно делаете, а затем инициализируйте сетку kedno с идентификатором таблицы следующим образом:

$(document).ready(function () {
        $("#grid").kendoGrid({
            height: 550,
            sortable: true,
            scrollable: true,
            filterable: true,
            pageable: {
                input: true,
                numeric: false
            },
        });
    });

Здесь сетка - это идентификатор таблицы. Это даст вашему бездумному столу разум, и вы сможете взаимодействовать с ним разными способами. В некоторой степени будут включены различные интерактивные функции, такие как сортировка, поиск / фильтрация и разбиение на страницы.

Этого подхода достаточно для случаев, когда ваша таблица содержит небольшой объем данных, например несколько сотен. В таких случаях нам не нужно беспокоиться о нашей серверной части. Просто включите необходимые библиотеки и запустите таблицу, используя несколько строк javascript.

Но это не идеальный сценарий, правда? В вашей таблице может быть от нескольких тысяч до миллионов данных. Если это так, то отрисовка таблицы с астрономическим числом строк и предоставление возможности кендо делать все - не кажется хорошей идеей. Потому что каждый раз, когда вы перезагружаете страницу или если к ней обращается много людей одновременно, это может вызвать кровотечение на сервере, и, очевидно, это будет медленным и на стороне клиентов.

Что мы можем сделать, так это не просто получить всю таблицу в начале, а получить ее часть и оставить пользователю возможность решать, сколько или какой набор данных он хочет видеть в таблице. Затем нам может потребоваться помощь сервера для правильной фильтрации или сортировки наших данных. Короче говоря, мы должны открывать каналы, чтобы позволить кендо и нашему серверу правильно общаться друг с другом.

На этот раз kendo будет работать не с таблицей HTML, а с данными json. Итак, нам нужно предоставить данные в формате json с сервера, и да, мы будем использовать для этого нашего верного друга DRF. Предположим, у меня есть модель Client, поэтому я собираюсь написать сериализатор и просматривать его с помощью DRF для моей модели. Мне также понадобится включить разбиение на страницы для начала, чтобы получить работающую привязку kendo-django. Поскольку это краткое руководство, для простоты я нарушу соглашение и напишу все в одном файле view.py.

class ClientPageNumberPagination(PageNumberPagination):
    page_size = 4
    page_size_query_param = 'pageSize'
class ClientSerializer(serializers.ModelSerializer):
    class Meta:
        model = Client
        fields = '__all__'
class ClientJsonView(generics.ListAPIView):
    serializer_class = ClientSerializer
    pagination_class = ClientPageNumberPagination
def get_queryset(self, *args, **kwargs):
             return Client.objects.all()

После подключения ClientJsonView с URL-адресом вы сможете получить json с включенной разбивкой на страницы с сервера. В моем случае у меня есть шаблон URL client_json, поэтому теперь я могу:

localhost:8000/client_json?page=2
localhost:8000/client_json?page=3

Здесь вы видите, что ответ json содержит несколько полей. Посчитайте, сколько объектов в модели. Следующее и предыдущее говорят сами за себя, и результаты содержат наши ожидаемые данные json, которые будет использовать kendo. Хотя у нас есть 10 записей, мы теперь будем видеть по 4 на каждой странице, потому что в ClientPageNumberPagination мы указали page_size равным 4. Мы также сказали, что page_size_query_param равно pageSize, поэтому, когда мы хотим изменить размер страницы, нам потребуется отправить размер с этим параметром следующим образом:

http://localhost:8000/client_json?page=2&pageSize=6

Мы могли бы установить page_size_query_param на любую допустимую строку во вселенной, но pageSize - это то, как говорит кендо.

Теперь нам нужно создать другое представление для обслуживания шаблона html. На этот раз шаблон не будет заполнен django. В основном он будет содержать div, а kendo будет читать данные json и отображать таблицу внутри этого элемента div.

class ClientListView(View):
    def get(self, *args, **kwargs):
        return render(self.request, "mainApp/client_list.html")

И важнейшая часть шаблона:

<body>
    <div id="grid">
    </div>
<script>
    $(document).ready(
        function () {
            var dataSourceArguments = {
                pageSize: 5,
                serverPaging: true,
                transport: {
                    read: {
                        url: "{% url 'client-json' %}",
                        dataType: "json",
                    }
                },
                schema: {
                    total: "count",
                    data: "results",
                }
            }
var ds = new kendo.data.DataSource(dataSourceArguments);
            $("#grid").kendoGrid({
                dataSource: ds,
                height: 600,
                filterable: true,
                sortable: true,
                pageable: {
                    refresh: true,
                    pageSizes: true,
                    buttonCount: 5
                },
                columns: [
                    {
                    field: "id",
                    title: "ID"
                    },
                    {
                    field: "name",
                    title: "Name"
                    },
                    {
                        field: "occupation",
                        title: "Occupation"
                    },
                    {
                        field: "date_of_birth",
                        title: "Birthday"
                    },
                ]
            });
}
);
</script>
</body>

Здесь вы можете видеть, что сетка инициализируется с использованием объекта источника данных, и во время инициализации мы сопоставили столбцы с полем json и указали заголовок столбца, остальные параметры такие же, как и раньше. В dataSourceArguments мы включили указанный начальный размер страницы равным 5 и включили разбиение по страницам на сервере.

schema: 
{
     total: "count",
     data: "results",
}

Помните результат json. Общее количество объектов было в поле количество, а данные нашего запроса были в поле результаты. Это то, что мы указали в схеме.

Теперь посмотрим, как включить сортировку на стороне сервера. Вы можете видеть, что таблица все еще может быть отсортирована, но только для подмножества видимых данных / страницы.

Добавьте строку

serverSorting: true,

В объекте dataSourceArguments. Если вы перезагрузите страницу, вы увидите, что предыдущая сортировка теперь не работает. Но если вы нажмете на название столбца, вы увидите, что теперь получающий запрос на получение сервер имеет некоторые дополнительные параметры. Если вы попытаетесь распечатать запрос в функции get_queryset, вы можете увидеть что-то вроде этого:

‹QueryDict: {u'pageSize ': [u'12'], u'skip ': [u'0'], u'take ': [u'12'], u'sort [0] [ dir] ': [u'desc'], u'sort [0] [поле] ': [u'name'], u'page ': [u'1']} ›

Or

‹QueryDict: {u'pageSize ': [u'12'], u'skip ': [u'0'], u'take ': [u'12'], u'sort [0] [ dir] ': [u'asc'], u'sort [0] [поле] ': [u'occupation'], u'page ': [u'1']} ›

Вы наверняка заметили из смелых заявлений, что на самом деле он дает нам все необходимое для выполнения действия по сортировке. Как и в первом запросе, он имеет порядок сортировки по убыванию, а поле, на основе которого будет выполняться сортировка, - это имя. В последнем случае порядок сортировки возрастающий, а поле - занятость.

Теперь вы можете изменить свое представление следующим образом:

class ClientJsonView(generics.ListAPIView):
    serializer_class = ClientSerializer
    pagination_class = ClientPageNumberPagination
def get_queryset(self, *args, **kwargs):
        clients = Client.objects.all()
        direction = ''
        field = ''
try:
            direction = self.request.GET['sort[0][dir]']
            field = self.request.GET['sort[0][field]']
        except:
            pass
if direction == 'asc':
            clients = clients.order_by(field)
        elif direction == 'desc':
            clients = clients.order_by('-'+field)
        else:
            return clients
return clients

Итак, это основы. Другие компоненты Kendo также могут быть инициализированы с использованием пользовательских данных с сервера с аналогичным подходом.

Вы можете найти весь код здесь,

Удачного кодирования :)