CBV 使用 django-filter 和 django-table2

CBV using django-filter with django-table2

我想将 django-table2 与 django-filter 一起使用。 我做了 django-table2 文件说,但我的模板中没有显示 django-filter 的形式。

这些是我的代码:

    # Views.py 
    from django_filters.views import FilterView
    import django_filters
    from django_tables2 import SingleTableView
    
    class MYFilter(django_filters.FilterSet):
        class Meta:
            model = MyModel
            fields = ['field1', 'field2' ]
    
    class MyView(SingleTableView, FilterView):
         model = MyModel
         table_class = MyTable
         template_name = 'my_template.html'
         filterset_class = MYFilter
    
    # tables.py 
    import django_tables2 as tables
    class MyTable(tables.Table):
        class Meta:
            model = MyModel
            fields = ("field1", "field2",)
    
    # my_template.html
    {% load render_table from django_tables2 %}
    {% if filter %}
    <form method="get">
        {{ filter.form.as_p }}
        <input type="submit" />
    </form>
    {% endif %}
    {% if table %}
    <div class="table-responsive">
        {% render_table table %}
    </div>
    {% endif %}

table 正确呈现,但表单未呈现。我的代码有什么问题?

正如@willem-van-onsem所说,你使用了两个baseclasses。所以你必须改变这一行:

class MyView(SingleTableView, FilterView):

对此:

class MyView(SingleTableMixin, FilterView):

您可以在本 link 中查看 django-table2 使用文档 django-filter

方法解析顺序 (MRO) 会将过滤器视图放低到没有影响,确实:

>>> MyView.__mro__
(<class 'MyView'>,
 <b><class 'django_tables2.views.SingleTableView'></b>,
 <class 'django_tables2.views.SingleTableMixin'>,
 <class 'django_tables2.views.TableMixinBase'>,
 <class 'django.views.generic.list.ListView'>,
 <class 'django_filters.views.FilterView'>,
 <class 'django.views.generic.list.MultipleObjectTemplateResponseMixin'>,
 <class 'django.views.generic.base.TemplateResponseMixin'>,
 <b><class 'django.views.generic.list.BaseListView'></b>,
 <b><class 'django_filters.views.BaseFilterView'></b>,
 <class 'django_filters.views.FilterMixin'>,
 <class 'django.views.generic.list.MultipleObjectMixin'>,
 <class 'django.views.generic.base.ContextMixin'>,
 <class 'django.views.generic.base.View'>,
 <class 'object'>)

这很重要,因为 BaseFilterView 将覆盖 get 方法,但由于 BaseListView 在 MRO 中首先出现,因此不会产生任何影响。如果我们交换 parents,那么:

class MyView(<b>FilterView, SingleTableView</b>):
    # …

mro 是:

>>> MyView.__mro__
(<class 'MyView'>,
 <class 'django_filters.views.FilterView'>,
 <class 'django_tables2.views.SingleTableView'>,
 <class 'django_tables2.views.SingleTableMixin'>,
 <class 'django_tables2.views.TableMixinBase'>,
 <class 'django.views.generic.list.ListView'>,
 <class 'django.views.generic.list.MultipleObjectTemplateResponseMixin'>,
 <class 'django.views.generic.base.TemplateResponseMixin'>,
 <b><class 'django_filters.views.BaseFilterView'></b>,
 <class 'django_filters.views.FilterMixin'>,
 <b><class 'django.views.generic.list.BaseListView'></b>,
 <class 'django.views.generic.list.MultipleObjectMixin'>,
 <class 'django.views.generic.base.ContextMixin'>,
 <class 'django.views.generic.base.View'>,
 <class 'object'>)

因此将使用 BaseFilterViewget 逻辑。