I am trying to create a table view with pagination, sorting, and filtering, using the most common/standard/recommended approach for Django 1.6. This seems to be Generic Class-Based Views and django-tables2. I've found at least two different examples of how to add filtering, one with django-filters and crispy-forms and the other with django_filters, but neither includes a complete working example. When I follow either approach, I get stuck filling in the missing material. Using the crispy approach from Nicolas Kuttler, I have:
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
If I understand correctly, PagedFilteredTableView is a generic class from which I then subclass AuthorView, as opposed to the other example, in which FilteredSingleTableView is, I think, supposed to be understood as something like, if Author was the table, 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
This is, aside from the template, all of the example code from the source, and manage.py is complaining that AuthorFilter isn't defined, so I guess that goes into ... maybe filters.py?
filters.py
import django_filters as df
from .models import Author
class AuthorFilter(df.FilterSet):
class Meta:
model = Author
And, back in views.py
, from .filters import AuthorFilter
.
And now AuthorFilterFormHelper
isn't defined, and it's not clear if that's something I should explicitly define (how?), as implied by the line formhelper_class = FooFilterFormHelper
, or if that should actually be done automatically somehow, as implied by self.filter.form.helper = self.formhelper_class()
. And we still haven't gotten to urls.py or the template. Please help fill in the blanks, or indicate a better path to go down to add filtering to a generic class-based view.