Django表 - 列过滤 [英] Django Tables - Column Filtering

查看:105
本文介绍了Django表 - 列过滤的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始使用 django-tables2 (我可以从第一印象中强烈推荐)我问自己如何实现列过滤。我没有找到合适的文档,但我确定它在某处。

I started using django-tables2 (which I can highly recommend from the first impression) and I m asking myself how to implement column filtering. I do not find the appropriate documentation for it, but I m sure it is somewhere out there.

推荐答案

稍晚的答案反正我也找不到任何适用于列过滤的文档。有很多方法可以实现:

A little late answer but anyway ... I also couldn't find any appropriate documentation for column filtering. There are many methods to do it:

A。手动:我添加一个包含我要过滤的字段的表单,然后在我的视图中进行这样的操作:

A. By hand: I add a form containing the fields I'd like to filter with and then I do something like this in my view:


  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)

这个工作非常好然而,它并不那么干,因为它是视图中的硬编码。

This works very nice however it's not so DRY because it is hard coded in the view.

B。使用SingleTableView :另一种方法是添加一个包含以下形式的SingleTableView:

B. Using a SingleTableView: Another way is to add a SingleTableView that contains the form:


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

更多DRY:)

C。使用SingleTableView和django_filters :这可能是最DRY的方式:)以下是如何做到:

C. Using SingleTableView and django_filters: This probably is the most DRY way :) Here's how to do it:

首先定义一个过滤器:


class MyFilter(django_filters.FilterSet):
  field1 = django_filters.CharFilter()
  field2 = django_filters.CharFilter()
...

(或者您可以在Meta(model = MyModel)中添加模型过滤器

(or you can add a model filter in Meta ( model = MyModel)

现在,创建一个这样的SingleTableView

Now, create a SingleTableView like this


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 = ...有一个问题,但我无法使其它工作。

(probably there is a problem with the line f =... but I couldn't make it work otherwise.

最后,您可以像这样从urls.py调用SingleTableView

Finally, you can call the SingleTableView from your urls.py like this


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.使用通用类:这是一个更加干燥和django泛型类视图的方式!这实际上是从 C 的下一步:只需声明您的FilteredSingleTableView,如下所示:

D. Using a generic class: This is an even more DRY and django-generic-class-views like way! This is actually the next step from C: Just declare your FilteredSingleTableView like this:


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中:

Now the FilteredSingleTableView has a parameter for the class of the filter so you may pass it in your urls.py among the other parameters:


    url(r'^$', ships.views.FilteredSingleTableView.as_view(
        model=models.MyModel,
        table_class=tables.MyTable, 
        template_name='mytemplate.html' , 
        filter_class = filters.MyFilter, 
    ) , name='myview'),

所以你可以使用FilteredSingleTableView,而无需修改过滤您的任何模型!!

So you can use FilteredSingleTableView without modifications for filtering any of your models !!

另请注意,我现在已将过滤器保存为实例变量,并删除重复代码 f = filters.MyFilter(...)我在 C (get_table_data在get_context_data之前调用) - 如果不是这样,那么我们可以添加一个 get_filter 实例方法,这将是诀窍)!

Also notice that I've now saved the filter as an instance variable and removed the repetitive code f=filters.MyFilter(...) that I had in C (get_table_data is called before get_context_data - if that was not always the case then we could add an get_filter instance method that would do the trick) !

更新23/04/2016 :在受欢迎的需求之后,我创建了一个简单的Django项目,它使用通用的FilteredSingleTableView类来过滤一张图表。您可以在以下网址找到: https://github.com/spapas/django_table_filtering

更新05/07/2016 :请注意,您应该使用 return self.filter.qs D 中的 get_table_data 返回(我已经通过此更新了答案),否则视图将花费太长时间才能呈现给大桌子 - - 有关 https://github.com/spapas/django_table_filtering/issues/1

Update 05/07/2016: Please notice that you should use return self.filter.qs for the get_table_data return in D (I've alread updated the answer with this) or else the view will take too long to render for big tables -- more info can be found on https://github.com/spapas/django_table_filtering/issues/1

这篇关于Django表 - 列过滤的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆