【问题标题】:How do I filter tables with Django generic views?如何使用 Django 通用视图过滤表?
【发布时间】:2014-10-05 01:07:07
【问题描述】:

我正在尝试使用 Django 1.6 中最常见/标准/推荐的方法创建具有分页、排序和过滤功能的表格视图。这似乎是基于类的通用视图和 django-tables2。我发现了至少两个不同的如何添加过滤的例子,一个是django-filters and crispy-forms,另一个是django_filters,但都没有一个完整的工作示例。当我采用任何一种方法时,我都无法填写缺失的材料。使用 Nicolas Kuttler 的脆皮方法,我有:

models.py

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)

tables.py

import django_tables2 as dt2
from .models import Author

class AuthorTable(dt2.Table):
    class Meta:
        model = Author

如果我理解正确,PagedFilteredTableView 是一个泛型类,然后我将其子类化为 AuthorView,与另一个示例相反,我认为 FilteredSingleTableView 应该被理解为,如果 Author 是表,AuthorFilteredSingleTableView .

views.py

from .tables import AuthorTable
from .models import Author
from django_tables2 import SingleTableView

class PagedFilteredTableView(SingleTableView):
    """
    Generic class from http://kuttler.eu/post/using-django-tables2-filters-crispy-forms-together/
    which should probably be in a utility file
    """
    filter_class = None
    formhelper_class = None
    context_filter_name = 'filter'

    def get_queryset(self, **kwargs):
        qs = super(PagedFilteredTableView, self).get_queryset()
        self.filter = self.filter_class(self.request.GET, queryset=qs)
        self.filter.form.helper = self.formhelper_class()
        return self.filter.qs

    def get_table(self, **kwargs):
        table = super(PagedFilteredTableView, self).get_table()
        RequestConfig(self.request, paginate={'page': self.kwargs['page'],
                            "per_page": self.paginate_by}).configure(table)
        return table

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

class AuthorTableView(PagedFilteredTableView):
    model = Author
    table_class = AuthorTable
    paginate_by = 30
    filter_class = AuthorFilter
    formhelper_class = AuthorFilterFormHelper

这是,除了模板,源代码中的所有示例代码,manage.py 抱怨未定义 AuthorFilter,所以我猜这会进入......也许是 filters.py?

filters.py

import django_filters as df
from .models import Author

class AuthorFilter(df.FilterSet):
    class Meta:
        model = Author

然后,回到views.pyfrom .filters import AuthorFilter

现在AuthorFilterFormHelper 没有定义,不清楚这是否是我应该明确定义的(如何?),正如formhelper_class = FooFilterFormHelper 行所暗示的那样,或者实际上应该以某种方式自动完成,正如暗示的那样通过self.filter.form.helper = self.formhelper_class()。而且我们还没有找到 urls.py 或模板。请帮助填写空白,或指出一条更好的路径,以将过滤添加到基于通用类的视图中。

【问题讨论】:

    标签: django django-class-based-views django-tables2 django-filter


    【解决方案1】:

    你的回答对我有帮助,所以我编辑了你的代码以包含来自crispy-forms的提交按钮

    forms.py。我无法弄清楚如何/在哪里从 django_filters 中获取表单提交按钮以及其他所有内容,因此这段代码会抑制表单包装器标签的脆性,然后我们在模板中提供该 HTML,这可能是最笨拙的部分。

    forms.py(已更新)

    from django import forms
    from .models import Author
    from crispy_forms.helper import FormHelper
    from crispy_forms.layout import Layout, ButtonHolder, Submit
    
    class AuthorListFormHelper(FormHelper):
        model = Author
        form_tag = False
        # Adding a Filter Button
        layout = Layout('name', ButtonHolder(
            Submit('submit', 'Filter', css_class='button white right')
        ))
    

    author-list.html(已更新)

    {% extends "base.html" %}
    {% load render_table from django_tables2 %}
    {% load crispy_forms_tags %}
    
    {% block content %}
    
    {% render_table table %}
    
    <hr/>
    <form action="" method="get"> 
        {% crispy filter.form filter.form.helper %}
    </form>
    
    {% endblock content %}
    

    【讨论】:

      【解决方案2】:

      通过反复试验和 Nicolas Kuttler 的一些建议,我能够让 his example 正常工作。我扼杀了他的一些例子,但这似乎确实接近 Django 中所需的最少代码量,以拥有一个具有排序、过滤(以及搜索)和分页的通用基于类的列表视图页面,我不不要认为它违反(太多)任何 Django 编码实践。以下是所需的所有代码:

      models.py(问题没有变化)

      from django.db import models
      
      class Author(models.Model):
          name = models.CharField(max_length=100)
      

      对问题中的 tables.py 稍作改动:

      import django_tables2 as dt2
      from .models import Author
      
      class AuthorTable(dt2.Table):
          class Meta:
              model = Author
              attrs = {"class": "paleblue"}
              per_page = 30
      

      filters.py(问题没有变化)

      import django_filters as df
      from .models import Author
      
      class AuthorFilter(df.FilterSet):
          class Meta:
              model = Author
      

      forms.py。我无法弄清楚如何/在哪里从 django_filters 中获取表单提交按钮以及其他所有内容,因此这段代码会抑制表单包装器标签的脆性,然后我们在模板中提供该 HTML,这可能是最笨的部分。

      from django import forms
      from .models import Author
      from crispy_forms.helper import FormHelper
      
      class AuthorListFormHelper(FormHelper):
          model = Author
          form_tag = False
      

      我将辅助函数从views.py 移到一个单独的文件中,并且必须删除分页代码以防止出现错误(尽管分页仍然有效)。所以,

      utils.py

      from django_tables2 import SingleTableView
      from django_tables2.config import RequestConfig
      
      class PagedFilteredTableView(SingleTableView):
          filter_class = None
          formhelper_class = None
          context_filter_name = 'filter'
      
          def get_queryset(self, **kwargs):
              qs = super(PagedFilteredTableView, self).get_queryset()
              self.filter = self.filter_class(self.request.GET, queryset=qs)
              self.filter.form.helper = self.formhelper_class()
              return self.filter.qs
      
          def get_context_data(self, **kwargs):
              context = super(PagedFilteredTableView, self).get_context_data()
              context[self.context_filter_name] = self.filter
              return context
      

      这个views.py

      代替了问题中的views.py
      from .models import Author
      from .tables import AuthorTable
      from .filters import AuthorListFilter
      from .forms import AuthorListFormHelper
      from utils import PagedFilteredTableView
      
      class AuthorList(PagedFilteredTableView):
          model = Author
          table_class = AuthorTable
          filter_class = AuthorListFilter
          formhelper_class = AuthorListFormHelper
      

      还有这个模板:

      author_list.html(我认为该名称没有在任何地方明确指定,因为它是由视图中的模型暗示的)

      {% extends "base.html" %}
      {% load render_table from django_tables2 %}
      {% load crispy_forms_tags %}
      
      {% block content %}
      
      {% render_table table %}
      
      <hr/>
      <form action="" method="get">
      {% crispy filter.form filter.form.helper %}
      <input type="submit" value="Filter"/>
      </form>
      
      {% endblock content %}
      

      为了完整起见,urls.py 中有一行:

          ...
          url(r'^$', views.AuthorTableList.as_view(), name='author_table'),
          ...
      

      并且您必须按照说明安装和配置包 django-tables2、django-filters 和crispy-forms。让我绊倒的一件事是,在第一次尝试时,我以某种方式错过了我在 settings.py 中需要它:

      CRISPY_TEMPLATE_PACK = 'bootstrap'
      

      所有这些都适用于 Django 1.6。

      【讨论】:

        猜你喜欢
        • 2017-12-24
        • 2017-02-18
        • 2017-12-01
        • 1970-01-01
        • 2010-12-05
        • 2013-07-17
        • 1970-01-01
        • 2013-03-07
        相关资源
        最近更新 更多