我正在尝试使用最常见/标准/推荐的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是一个泛型类,然后我将其作为子类,而不是另一个例子,其中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
除了模板之外,来自source和manage.py的所有示例代码都抱怨AuthorFilter没有被定义,所以我想这会进入...也许filters.py?< / p>
filters.py
import django_filters as df
from .models import Author
class AuthorFilter(df.FilterSet):
class Meta:
model = Author
然后,回到views.py
,from .filters import AuthorFilter
。
现在AuthorFilterFormHelper
尚未定义,并且我不清楚我应该明确定义的内容(如何?),如行{{1}所暗示的那样或者,如果实际上应该以某种方式自动完成,如formhelper_class = FooFilterFormHelper
暗示的那样。我们仍然没有得到urls.py或模板。请帮助填写空白,或指示更好的路径,以便将过滤添加到基于通用类的视图。
答案 0 :(得分:9)
经过反复试验和Nicolas Kuttler的一些建议,我得以his example工作。我宰了他的一些例子,但这看起来似乎接近Django所需的最少量的代码,有一个基于类的基于列表的查看页面,包括排序,过滤(以及搜索)和分页,我不知道#39;认为它违反了(太m)任何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中的表单提交按钮以及其他所有内容,因此此代码禁止表单包装器标签来自crispy,然后我们在模板中提供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。
答案 1 :(得分:2)
您的回答对我有帮助,因此我编辑了您的代码以包含来自crispy-forms的提交按钮
forms.py。我无法弄清楚如何/从何处获取django_filters中的表单提交按钮以及其他所有内容,因此这段代码会从crispy中抑制表单包装器标签,然后我们在模板中提供HTML,这可能是kludgiest部分内容。
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 %}