Skip to content

Commit

Permalink
Added SingleTableMixin that makes adding a table to a view trivially …
Browse files Browse the repository at this point in the history
…easy. Partially resolves #10.
  • Loading branch information
bradleyayers committed Jun 2, 2011
1 parent 9589d92 commit af701b4
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 0 deletions.
81 changes: 81 additions & 0 deletions django_tables/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from django.core.exceptions import ImproperlyConfigured
from django.views.generic.base import TemplateResponseMixin
from django.views.generic.list import BaseListView


class SingleTableMixin(object):
"""
Adds a Table object to the context. Typically used with
``TemplateResponseMixin``.
:param table_class: table class
:type table_class: subclass of ``django_tables.Table``
:param table_data: data used to populate the table
:type table_data: any compatible data source
:param context_table_name: name of the table's template variable (default:
"table")
:type context_table_name: ``string``
This mixin plays nice with the Django's ``MultipleObjectMixin`` by using
``get_queryset()`` as a fallback for the table data source.
"""
table_class = None
table_data = None
context_table_name = None

def get_table(self):
"""
Return a table object to use. The table has automatic support for
sorting and pagination.
"""
table_class = self.get_table_class()
table = table_class(self.get_table_data(),
order_by=self.request.GET.get("sort"))
table.paginate(page=self.request.GET.get("page", 1))
return table

def get_table_class(self):
"""
Return the class to use for the table.
"""
if self.table_class:
return self.table_class
raise ImproperlyConfigured(u"A table class was not specified. Define"
u"%(cls)s.table_class"
% {"cls": self.__class__.__name__})

def get_context_table_name(self, table):
"""
Get the name to use for the table's template variable.
"""
return self.context_table_name or "table"

def get_table_data(self):
"""
Return the table data that should be used to populate the rows.
"""
if self.table_data:
return self.table_data
elif hasattr(self, "get_queryset"):
return self.get_queryset()
raise ImproperlyConfigured(u"Table data was not specified. Define "
u"%(cls)s.table_data"
% {"cls": self.__class__.__name__})

def get_context_data(self, **kwargs):
"""
Overriden version of ``TemplateResponseMixin`` to inject the table into
the template's context.
"""
context = super(SingleTableMixin, self).get_context_data(**kwargs)
table = self.get_table()
context[self.get_context_table_name(table)] = table
return context


class SingleTableView(SingleTableMixin, TemplateResponseMixin, BaseListView):
"""
Generic view that renders a template and passes in a ``Table`` object.
"""
59 changes: 59 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,65 @@ which can be iterated over:
</table>
Class Based Generic Mixins
==========================

Django 1.3 introduced `class based views`__ as a mechanism to reduce the
repetition in view code. django-tables comes with a single class based view
mixin: ``SingleTableMixin``. It makes it trivial to incorporate a table into a
view/template, however it requires a few variables to be defined on the view:

- ``table_class`` –- the table class to use, e.g. ``SimpleTable``
- ``table_data`` (or ``get_table_data()``) -- the data used to populate the
table
- ``context_table_name`` -- the name of template variable containing the table
object

.. __: https://docs.djangoproject.com/en/1.3/topics/class-based-views/

For example:

.. code-block:: python
from django_tables.views import SingleTableMixin
from django.generic.views.list import ListView
class Simple(models.Model):
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
class SimpleTable(tables.Table):
first_name = tables.Column()
last_name = tables.Column()
class MyTableView(SingleTableMixin, ListView):
model = Simple
table_class = SimpleTable
The template could then be as simple as:

.. code-block:: django
{% load django_tables %}
{% render_table table %}
Such little code is possible due to the example above taking advantage of
default values and ``SimpleTableMixin``'s eagarness at finding data sources
when one isn't explicitly defined.

.. note::

If you want more than one table on a page, at the moment the simplest way
to do it is to use ``SimpleTableMixin`` for one table, and write the
boilerplate for the other yourself in ``get_context_data()``. Obviously
this isn't particularly elegant, and as such will hopefully be resolved in
the future.


API Reference
=============

Expand Down

0 comments on commit af701b4

Please sign in to comment.