我使用的是BaseDatatableView和DataTable jQuery.我已经为BaseDatatableView编写了几个视图,在我必须重写‘Prepare_Result’和‘Render_Column’方法之前没有任何问题.我需要在表中显示实例方法的结果,因此我覆盖了BaseDatatableView类的方法.

这是我在views.py中的代码

class MyModelDatatable(BaseDatatableView):
    model = MyModel
    columns = ['field1', 'field2', 'id']
    columns_searched = [col for col in columns if col != 'id']
    
    def get_initial_queryset(self):
        return self.model.objects.all()

    def filter_queryset(self, qs):
        print('test')  # not displayed
        search_text = self.request.GET.get('search[value]', None)
        if search_text:
            search_terms = search_text.split()
            query = Q()

            for col in self.columns_searched:
                or_conditions = Q()

                for term in search_terms:
                    or_conditions |= Q(**{f'{col}__icontains': term})

                query |= or_conditions    

            qs = qs.filter(query)

        return qs

    def prepare_results(self, qs):
        data = []
        for item in qs:
            item_str = str(item)
            data.append({

                'field1': item_str,
                'field2': item.field2,
                'id': item.id
            })

        return data

    def render_column(self, row, column):
        if column == 'field2':
            return row.field2.strftime('%Y-%m-%d')
        return super(OrderDatatable, self).render_column(row, column)

    def get(self, request, *args, **kwargs):
        return self.get_json_response()

    def get_json_response(self):
        draw = int(self.request.GET.get('draw', 1))
        total_records = self.get_initial_queryset().count()
        total_display_records = total_records
        start = int(self.request.GET.get('start', 0))
        length = int(self.request.GET.get('length', 10))
        end = start + length
        data = self.prepare_results(self.get_initial_queryset()[start:end])
        response = {
            'draw': draw,
            'recordsTotal': total_records,
            'recordsFiltered': total_display_records,
            'data': data,
        }

        return JsonResponse(response)

ObjDatable.js

$(document).ready(function () {
    const table = $('#my-datatable').DataTable({
        'columns': [

            {'data': 'field1'},
            {'data': 'field2'},
            {
                'data': 'id',
                'render': function (data, type, row) {
                    let actionButtons = `
                        <a  href='/edit/${data}'
                            class="btn btn-datatable btn-icon btn-transparent-dark me-2">
                            <i data-feather="edit"></i>
                        </a>
                    `;
                    return actionButtons;
                }
            },
    
        ],
        'paging': true,
        'pageLength': 20,
        'lengthMenu': [5, 10, 20, 30, 50, 100, 200],
        'pagingType': 'full_numbers',
        'processing': true,
        'serverSide': true,
        'ajax': {
            'url': 'orders_datatable_search/',
       
        }
    });
    table.on('draw.dt', function () {
        feather.replace();
    })
});

使用不带方法重写的标准类字段,筛选可以正常工作.覆盖后,所有内容都正常工作,包括分页,但不进行过滤.

推荐答案

您的get_json_response会生成项目,但它们完全省略了过滤、排序和分页逻辑,正如您在original implementation [GitHub]中看到的那样.

因此,您将不得不自己重新实现它:

class MyModelDatatable(BaseDatatableView):
    model = MyModel
    columns = ['field1', 'field2', 'id']
    columns_searched = [col for col in columns if col != 'id']

    def get_initial_queryset(self):
        return self.model.objects.all()

    def filter_queryset(self, qs):
        print('test')
        search_text = self.request.GET.get('search[value]', None)
        if search_text:
            search_terms = search_text.split()
            query = Q()
            for col in self.columns_searched:
                or_conditions = Q()
                for term in search_terms:
                    or_conditions |= Q(**{f'{col}__icontains': term})
                query |= or_conditions
            qs = qs.filter(query)
        return qs

    def prepare_results(self, qs):
        data = []
        for item in qs:
            item_str = str(item)
            data.append(
                {'field1': item_str, 'field2': item.field2, 'id': item.id}
            )
        return data

    def render_column(self, row, column):
        if column == 'field2':
            return row.date.strftime('%Y-%m-%d')
        return super(OrderDatatable, self).render_column(row, column)

    def paging(self, qs):
        start = int(self.request.GET.get('start', 0))
        length = int(self.request.GET.get('length', 10))
        return qs[start : start + length]

    def get(self, request, *args, **kwargs):
        return self.get_json_response()

    def get_json_response(self):
        draw = int(self.request.GET.get('draw', 1))
        qs = self.get_initial_queryset()
        total_records = qs.count()
        qs = self.filter_queryset(qs)
        total_display_records = qs.count()
        qs = self.ordering(qs)
        qs = self.paging(qs)
        response = {
            'draw': draw,
            'recordsTotal': total_records,
            'recordsFiltered': total_display_records,
            'data': data,
        }
        return JsonResponse(response)

然而,我并不是真的理解您为什么在这里再次实现整个逻辑.这几乎等同于原来的.因此,只需覆盖paging方法和其他一些方法,就可以让BaseDatatableView视图处理逻辑.它将返回一个JsonResponseanway,因此您正在重新实现样板代码.

Jquery相关问答推荐

如何用 jQuery / AJAX 替换表格的行

Jquery 表数据无法在 html 上正确显示

在函数 jQuery 中更改语言

jQuery 上传进度和 AJAX 文件上传

自动完成时触发的任何事件?

JQuery/Javascript:判断 var 是否存在

在 jQuery UI Datepicker 中禁用future 日期

我们如何在不重新加载页面的情况下使用 javascript/jQuery 更新 URL 或查询字符串?

如何判断是否有任何 JavaScript 事件侦听器/处理程序附加到元素/文档?

可以在不使用for=id的情况下将标签与复选框相关联吗?

从 JQuery.ajax 成功数据中解析 JSON

jQuery切换文本?

单击后如何禁用提交按钮?

jQuery:获取父母,父母ID?

jQuery 日期 Select 器 - 禁用过go 的日期

如何从所有元素jquery中删除类

当 iframe 在 jQuery 中完成加载时,如何触发事件?

jQuery DataTables:控制表格宽度

如何删除集中的 contenteditable pre 周围的边框?

自调用函数前的分号?