我开始使用django-tables2(从第一印象中就可以强烈推荐),我问自己如何实现列过滤。我找不到合适的文档,但是我确定它在那里。
答案有点晚了,但是无论如何…我也找不到任何合适的文档来进行列过滤。有很多方法可以做到这一点:
答:手动:我添加了一个包含要过滤的字段的表单,然后在我的视图中执行以下操作:
data = models.MyClass.all() form = forms.MyFilterForm(request.GET) if request.GET.get('field1'): data = data.filter(field1=request.GET.get('field1') ) if request.GET.get('field2'): data = data.filter(field2=request.GET.get('field2') ) ... table = tables.MyTable(data)
这很好用,但是不是那么干,因为它在视图中是硬编码的。
B.使用SingleTableView:另一种方法是添加包含以下形式的SingleTableView:
from django_tables2 import SingleTableView class FilteredSingleTableView(SingleTableView): def get_table_data(self): data= models.MyClass.objects.all if self.request.GET.get('field1'): data = data.filter(field1=self.request.GET.get('field1') ) if self.request.GET.get('field1'): data = data.filter(field1=self.request.GET.get('field1') ) return data def get_context_data(self, **kwargs): context = super(FilteredSingleTableView, self).get_context_data(**kwargs) context['form'] = forms.MyFilterForm(self.request.user, self.request.GET) return context
C.使用SingleTableView和django_filters:这可能是最干的方法:)这是这样做的方法:
首先定义一个过滤器:
class MyFilter(django_filters.FilterSet): field1 = django_filters.CharFilter() field2 = django_filters.CharFilter() ...
(或者你可以在Meta中添加模型过滤器(model = MyModel)
现在,像这样创建SingleTableView
class FilteredSingleTableView(SingleTableView): def get_table_data(self): f = filters.MyFilter(self.request.GET, queryset =models.MyClass.objects.all() , request=self.request ) return f def get_context_data(self, **kwargs): context = super(FilteredSingleTableView, self).get_context_data(**kwargs) f = filters.MyFilter(self.request.GET, queryset =models.MyClass.objects.all() , request=self.request ) context['form'] = f.form return context
(可能f = …行有问题,但我无法使其工作。
最后,你可以像这样从urls.py调用SingleTableView
url(r'^ $',views.FilteredSingleTableView.as_view( table_class = tables.MyTable, model = models.MyClass, template_name ='mytemplate.html', table_pagination = {“ per_page”:50})), name ='filtered_single_table_view' ),
D.使用泛型类:这是一种更加干的DRY和django-generic-class-views方式!这实际上是C的下一步:像这样声明你的FilteredSingleTableView:
class FilteredSingleTableView(django_tables2.SingleTableView): filter_class = None def get_table_data(self): self.filter = self.filter_class(self.request.GET, queryset =super(FilteredSingleTableView, self).get_table_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
现在,FilteredSingleTableView具有用于过滤器类的参数,因此你可以在其他参数中将其传递到urls.py中:
url(r'^ $',ship.views.FilteredSingleTableView.as_view( model = models.MyModel, table_class = tables.MyTable, template_name ='mytemplate.html', filter_class = filters.MyFilter, ),name ='myview'),
因此,你可以使用FilteredSingleTableView而无需进行修改即可过滤任何模型!
还要注意,我现在已经将过滤器另存为一个实例变量,并删除了f=filters.MyFilter(…)我在C中拥有的重复代码(get_table_data在get_context_data之前被调用-如果并非总是如此,那么我们可以添加一个get_filter实例方法来解决问题)!