在大表上使用 Django-Filter 以及 DataTables2

Posted

技术标签:

【中文标题】在大表上使用 Django-Filter 以及 DataTables2【英文标题】:Usage of Django-Filter on large tables along with DataTables2 【发布时间】:2016-11-06 14:21:38 【问题描述】:

我正在使用带有以下代码的 Django-Tables2 将数据加载到数据表中。

sales_data = SalesTable(sale.objects.all().order_by('-time'))
RequestConfig(request,paginate='per_page': 50).configure(sales_data)

我的 Sales 表有 140 万行,然而,上述 RequestConfig on (django_tables2.Table) 方法在分页等方面非常快。

现在,我想对表格进行列过滤,并使用 django-filter 进行过滤。它花费的时间太长,消耗了整个内存。有没有办法让过滤的速度和正常的表格加载一样快?

views.py

class FilteredSingleTableView(tables.SingleTableView):
      filter_class = None

      def get_table_data(self):
         queryset_data = super(FilteredSingleTableView, self).get_table_data()
         self.filter = self.filter_class(self.request.GET, queryset = queryset_data)
         return self.filter

      def get_context_data(self, **kwargs):
         context = super(FilteredSingleTableView, self).get_context_data(**kwargs)
         context['filter'] = self.filter
         return context 


class SalesFilteredSingleTableView(FilteredSingleTableView):
      model = sale
      table_class = sales.tables.SaleFilteredTable
      filter_class = sales.filters.SaleFilter

urls.py

url(r'^filtertest$', sales_views.SalesFilteredSingleTableView.as_view() , name='salesfilterview')

filters.py

import django_filters

import sales.models

class SaleFilter(django_filters.FilterSet):
    class Meta:
        model = sales.models.sale

tables.py

import django_tables2 as tables
from sales.models import sale

class SaleFilteredTable(tables.Table):
    class Meta:
        model = sale
        attrs = "class": "paleblue"
        per_page = 50

提前致谢!

【问题讨论】:

为什么需要使用django过滤器?内置过滤器有什么问题? Django-Filter 的查询集根据 filter-form 定义了动态列过滤本身,我们不需要为所有字段类型重新发明一切。 你有比交易吹嘘更好的理由吗? @e4c5 使用 Django-filter,自定义/插入新的过滤器和类型非常容易。在这种方法中,我注意到多个表的加载时间显着下降。 【参考方案1】:

在 CBV 中,必须传递 filter.qs 而不是 filter。在前一种情况下,整个表被加载到内存中,因此加载时间更长,并且发生了浏览器崩溃。

通过此修改,空过滤器和过滤器查询集都加载了 LIMIT Query。

views.py

class FilteredSingleTableView(tables.SingleTableView):
filter_class = None

def get_table_data(self):
    queryset_data = super(FilteredSingleTableView, self).get_table_data()
    self.filter = self.filter_class(self.request.GET, queryset = queryset_data)
    return self.filter.qs

def get_context_data(self, **kwargs):
    context = super(FilteredSingleTableView, self).get_context_data(**kwargs)
    context['filter'] = self.filter
    return context 

class SalesFilteredSingleTableView(FilteredSingleTableView):
    model = sale
    table_class = SalesFilteredTable
    template_name = 'sales/sale_list.html'
    filter_class = sales.filters.SaleFilter

参考

https://github.com/carltongibson/django-filter/issues/442

【讨论】:

只是好奇……什么是“CBV”? @JasonCapriotti 在 Django 中,基于类的视图简称为 CBV。

以上是关于在大表上使用 Django-Filter 以及 DataTables2的主要内容,如果未能解决你的问题,请参考以下文章

MySQL查询在大表上很慢

如何在大表上优化这个 mysql 连接?

如何使用具有多个 GROUP BY、子查询和 WHERE IN 在大表上的查询来优化查询?

尽可能快地获取我的 MySQL 的第一行(也在大表上)

必须在大表上的 .Skip() 和 .Take() 之前在实体框架 4.1 中调用 .ToList()

经验分享为什么hive在大表上加条件后执行limit很慢