3 ================================================
4 django-tables2 - An app for creating HTML tables
5 ================================================
7 django-tables2 simplifies the task of turning sets of datainto HTML tables. It
8 has native support for pagination and sorting. It does for HTML tables what
9 ``django.forms`` does for HTML forms.
14 1. Download and install from https://github.com/bradleyayers/django-tables2.
15 Grab a ``.tar.gz`` of the latest tag, and run ``pip install <tar.gz>``.
16 2. Hook the app into your Django project by adding ``'django_tables2'`` to your
17 ``INSTALLED_APPS`` setting.
18 3. Write a subclass of :class:`~django_tables2.tables.Table` that describes the
19 structure of your table.
20 4. Create an instance of your table in a :term:`view`, provide it with
21 :term:`table data`, and pass it to a :term:`template` for display.
22 5. Use ``{{ table.as_html }}``, the
23 :ref:`template tag <template-tags.render_table>`, or your own
24 :ref:`custom template <custom-template>` to display the table.
30 We're going to take some data that describes three countries and
31 turn it into an HTML table. This is the data we'll be using:
33 .. code-block:: python
36 {'name': 'Australia', 'population': 21, 'tz': 'UTC +10', 'visits': 1},
37 {'name': 'Germany', 'population': 81, 'tz': 'UTC +1', 'visits': 2},
38 {'name': 'Mexico', 'population': 107, 'tz': 'UTC -6', 'visits': 0},
42 The first step is to subclass :class:`~django_tables2.tables.Table` and describe
43 the table structure. This is done by creating a column for each attribute in
44 the :term:`table data`.
46 .. code-block:: python
48 import django_tables2 as tables
50 class CountryTable(tables.Table):
51 name = tables.Column()
52 population = tables.Column()
53 tz = tables.Column(verbose_name='Time Zone')
54 visits = tables.Column()
57 Now that we've defined our table, it's ready for use. We simply create an
58 instance of it, and pass in our table data.
60 .. code-block:: python
62 table = CountryTable(countries)
64 Now we add it to our template context and render it to HTML. Typically you'd
65 write a view that would look something like:
67 .. code-block:: python
70 table = CountryTable(countries)
71 return render_to_response('home.html', {'table': table},
72 context_instance=RequestContext(request))
74 In your template, the easiest way to :term:`render` the table is via the
75 :meth:`~django_tables2.tables.Table.as_html` method:
77 .. code-block:: django
81 …which will render something like:
83 +--------------+------------+-----------+--------+
84 | Country Name | Population | Time Zone | Visit |
85 +==============+============+===========+========+
86 | Australia | 21 | UTC +10 | 1 |
87 +--------------+------------+-----------+--------+
88 | Germany | 81 | UTC +1 | 2 |
89 +--------------+------------+-----------+--------+
90 | Mexico | 107 | UTC -6 | 0 |
91 +--------------+------------+-----------+--------+
93 This approach is easy, but it's not fully featured (e.g. no pagination, no
94 sorting). Don't worry it's very easy to add these. First, you must render the
95 table via the :ref:`template tag <template-tags.render_table>` rather than
98 .. code-block:: django
100 {% load django_tables2 %}
101 {% render_table table %}
105 ``{% render_table %}`` requires that the ``TEMPLATE_CONTEXT_PROCESSORS``
106 setting contains ``"django.core.context_processors.request"``. See
107 :ref:`template-tags.render_table` for details.
109 This is all that's required for the template, but in the view you'll need to
110 tell the table to which column to order by, and which page of data to display
111 (pagination). This is achieved as follows:
113 .. code-block:: python
116 countries = Country.objects.all()
117 table = CountryTable(countries, order_by=request.GET.get('sort'))
118 table.paginate(page=request.GET.get('page', 1))
119 return render_to_response('home.html', {'table': table},
120 context_instance=RequestContext(request))
122 See :ref:`ordering`, and :ref:`pagination` for more information.
124 The table will be rendered, but chances are it will still look quite ugly. An
125 easy way to make it pretty is to use the built-in *paleblue* theme. For this to
126 work, you must add a CSS class to the ``<table>`` tag. This can be achieved by
127 adding a ``class Meta:`` to the table class and defining a ``attrs`` variable.
129 .. code-block:: python
131 import django_tables2 as tables
133 class CountryTable(tables.Table):
134 name = tables.Column()
135 population = tables.Column()
136 tz = tables.Column(verbose_name='Time Zone')
137 visits = tables.Column()
140 attrs = {'class': 'paleblue'}
142 The last thing to do is to include the stylesheet in the template.
146 <link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}django_tables2/themes/paleblue/css/screen.css" />
148 Save your template and reload the page in your browser.
156 The data used to populate a table is called :term:`table data`. To provide a
157 table with data, pass it in as the first argument when instantiating a table.
159 .. code-block:: python
161 table = CountryTable(countries) # valid
162 table = CountryTable(Country.objects.all()) # also valid
164 Each item in the :term:`table data` is called a :term:`record` and is used to
165 populate a single row in the table. By default, the table uses column names
166 as :term:`accessors <accessor>` to retrieve individual cell values. This can
167 be changed via the :attr:`~django_tables2.columns.Column.accessor` argument.
169 Any iterable can be used as table data, and there's builtin support for
170 :class:`QuerySet` objects (to ensure they're handled effeciently).
180 If you want to change the order in which columns are displayed, see
181 :attr:`Table.Meta.sequence`. Alternatively if you're interested in the
182 order of records within the table, read on.
184 Changing the way records in a table are ordered is easy and can be controlled
185 via the :attr:`.Table.Meta.order_by` option. The following examples all achieve
188 .. code-block:: python
190 class SimpleTable(tables.Table):
191 name = tables.Column()
196 By passing in a value for ``order_by`` into the ``Table`` constructor, the
197 ``Meta.order_by`` option can be overridden on a per-instance basis.
199 .. code-block:: python
201 class SimpleTable(tables.Table):
202 name = tables.Column()
204 table = SimpleTable(..., order_by='name')
206 This approach allows column sorting to be enabled for use with the ``{%
207 render_table %}`` template tag. The template tag converts column headers into
208 hyperlinks that add the querystring parameter ``sort`` to the current URL. This
209 means your view will need to look something like:
211 .. code-block:: python
214 countries = Country.objects.all()
215 table = CountryTable(countries, order_by=request.GET.get('sort'))
216 return render_to_response('home.html', {'table': table},
217 context_instance=RequestContext(request))
219 The final approach allows both of the previous approaches to be overridden. The
220 instance property ``order_by`` can be
222 .. code-block:: python
224 class SimpleTable(tables.Table):
225 name = tables.Column()
227 table = SimpleTable(...)
228 table.order_by = 'name'
232 By default all table columns support sorting. This means that if you're using
233 the :ref:`template tag <template-tags.render_table>` to render the table,
234 users can sort the table based on any column by clicking the corresponding
237 In some cases this may not be appropriate. For example you may have a column
238 which displays data that isn't in the dataset:
240 .. code-block:: python
242 class SimpleTable(tables.Table):
243 name = tables.Column()
244 lucky_rating = tables.Column()
249 def render_lucky_rating(self):
251 return random.randint(1, 10)
253 In these types of scenarios, it's simply not possible to sort the table based
254 on column data that isn't in the dataset. The solution is to disable sorting
257 Sorting can be disabled on a column, table, or table instance basis via the
258 :attr:`.Table.Meta.sortable` option.
260 To disable sorting by default for all columns:
262 .. code-block:: python
264 class SimpleTable(tables.Table):
265 name = tables.Column()
270 To disable sorting for a specific table instance:
272 .. code-block:: python
274 class SimpleTable(tables.Table):
275 name = tables.Column()
277 table = SimpleTable(..., sortable=False)
279 table.sortable = False
287 The header cell for each column comes from the column's
288 :meth:`~django_tables2.columns.BoundColumn.header` method. By default this
289 method returns the column's ``verbose_name``, which is either explicitly
290 specified, or generated automatically based on the column name.
292 When using queryset input data, rather than falling back to the column name if
293 a ``verbose_name`` has not been specified explicitly, the queryset model's
294 field ``verbose_name`` is used.
296 Consider the following:
298 >>> class Person(models.Model):
299 ... first_name = models.CharField(verbose_name='FIRST name', max_length=200)
300 ... last_name = models.CharField(max_length=200)
301 ... region = models.ForeignKey('Region')
303 >>> class Region(models.Model):
304 ... name = models.CharField(max_length=200)
306 >>> class PersonTable(tables.Table):
307 ... first_name = tables.Column()
308 ... ln = tables.Column(accessor='last_name')
309 ... region_name = tables.Column(accessor='region.name')
311 >>> table = PersonTable(Person.objects.all())
312 >>> table.columns['first_name'].verbose_name
314 >>> table.columns['ln'].verbose_name
316 >>> table.columns['region_name'].verbose_name
319 As you can see in the last example, the results are not always desirable when
320 an accessor is used to cross relationships. To get around this be careful to
321 define a ``verbose_name`` on such columns.
329 Pagination is easy, just call :meth:`.Table.paginate` and pass in the current
332 .. code-block:: python
334 def people_listing(request):
335 table = PeopleTable(Person.objects.all())
336 table.paginate(page=request.GET.get('page', 1))
337 return render_to_response('people_listing.html', {'table': table},
338 context_instance=RequestContext(request))
340 The last set is to render the table. :meth:`.Table.as_html` doesn't support
341 pagination, so you must use :ref:`{% render_table %}
342 <template-tags.render_table>`.
344 .. _custom-rendering:
349 Various options are available for changing the way the table is :term:`rendered
350 <render>`. Each approach has a different balance of ease-of-use and
356 In order to use CSS to style a table, you'll probably want to add a
357 ``class`` or ``id`` attribute to the ``<table>`` element. ``django-tables2`` has
358 a hook that allows abitrary attributes to be added to the ``<table>`` tag.
360 .. code-block:: python
362 >>> import django_tables2 as tables
363 >>> class SimpleTable(tables.Table):
364 ... id = tables.Column()
365 ... age = tables.Column()
368 ... attrs = {'class': 'mytable'}
370 >>> table = SimpleTable()
372 '<table class="mytable">...'
375 .. _table.render_foo:
377 :meth:`Table.render_FOO` Methods
378 --------------------------------
380 If you want to adjust the way table cells in a particular column are rendered,
381 you can implement a ``render_FOO`` method. ``FOO`` is replaced with the
382 :term:`name <column name>` of the column.
384 This approach provides a lot of control, but is only suitable if you intend to
385 customise the rendering for a single table (otherwise you'll end up having to
386 copy & paste the method to every table you want to modify – which violates
389 For convenience, a bunch of commonly used/useful values are passed to
390 ``render_FOO`` functions, when writing the signature, simply accept the
391 arguments you're interested in, and the function will recieve them
393 .. note:: Due to the implementation, a "catch-extra" arguments (e.g. ``*args``
394 or ``**kwargs``) will not recieve any arguments. This is because
395 ``inspect.getargsspec()`` is used to check what arguments a ``render_FOO``
396 method expect, and only to supply those.
398 :param value: the value for the cell retrieved from the :term:`table data`
399 :param record: the entire record for the row from :term:`table data`
400 :param column: the :class:`.Column` object
401 :param bound_column: the :class:`.BoundColumn` object
402 :param bound_row: the :class:`.BoundRow` object
403 :param table: alias for ``self``
405 .. code-block:: python
407 >>> import django_tables2 as tables
408 >>> class SimpleTable(tables.Table):
409 ... row_number = tables.Column()
410 ... id = tables.Column()
411 ... age = tables.Column()
413 ... def render_row_number(self):
414 ... value = getattr(self, '_counter', 0)
415 ... self._counter = value + 1
416 ... return 'Row %d' % value
418 ... def render_id(self, value):
419 ... return '<%s>' % value
421 >>> table = SimpleTable([{'age': 31, 'id': 10}, {'age': 34, 'id': 11}])
422 >>> for cell in table.rows[0]:
430 .. _subclassing-column:
432 Subclassing :class:`Column`
433 ---------------------------
435 If you want to have a column behave the same way in many tables, it's best to
436 create a subclass of :class:`Column` and use that when defining the table.
438 To change the way cells are rendered, simply override the
439 :meth:`~Column.render` method.
441 .. code-block:: python
443 >>> import django_tables2 as tables
445 >>> class AngryColumn(tables.Column):
446 ... def render(self, value):
447 ... return value.upper()
449 >>> class Example(tables.Table):
450 ... normal = tables.Column()
451 ... angry = AngryColumn()
454 ... 'normal': 'May I have some food?',
455 ... 'angry': 'Give me the food now!',
457 ... 'normal': 'Hello!',
458 ... 'angry': 'What are you looking at?',
461 >>> table = Example(data)
463 u'<table><thead><tr><th>Normal</th><th>Angry</th></tr></thead><tbody><tr><td>May I have some food?</td><td>GIVE ME THE FOOD NOW!</td></tr><tr><td>Hello!</td><td>WHAT ARE YOU LOOKING AT?</td></tr></tbody></table>\n'
465 See :ref:`table.render_foo` for a list of arguments that can be accepted.
467 Which, when displayed in a browser, would look something like this:
469 +-----------------------+--------------------------+
471 +=======================+==========================+
472 | May I have some food? | GIVE ME THE FOOD NOW! |
473 +-----------------------+--------------------------+
474 | Hello! | WHAT ARE YOU LOOKING AT? |
475 +-----------------------+--------------------------+
478 For complicated columns, it's sometimes necessary to return HTML from a :meth:`~Column.render` method, but the string
479 must be marked as safe (otherwise it will be escaped when the table is
480 rendered). This can be achieved by using the :func:`mark_safe` function.
482 .. code-block:: python
484 >>> from django.utils.safestring import mark_safe
486 >>> class ImageColumn(tables.Column):
487 ... def render(self, value):
488 ... return mark_safe('<img src="/media/img/%s.jpg" />' % value)
497 And of course if you want full control over the way the table is rendered,
498 ignore the built-in generation tools, and instead pass an instance of your
499 :class:`Table` subclass into your own template, and render it yourself:
501 .. code-block:: django
503 {% load django_tables2 %}
507 {% for column in table.columns %}
508 <th><a href="{% set_url_param sort=column.name_toggled %}">{{ column }}</a></th>
513 {% for row in table.rows %}
515 {% for cell in row %}
520 {% if table.empty_text %}
521 <tr><td colspan="{{ table.columns|length }}">{{ table.empty_text }}</td></tr>
533 .. _template-tags.render_table:
538 Renders a :class:`~django_tables2.tables.Table` object to HTML and includes as
539 many features as possible.
543 .. code-block:: django
545 {% load django_tables2 %}
546 {% render_table table %}
548 This tag temporarily modifies the :class:`.Table` object while it is being
549 rendered. It adds a ``request`` attribute to the table, which allows
550 :class:`Column` objects to have access to a ``RequestContext``. See
551 :class:`.TemplateColumn` for an example.
553 This tag requires that the template in which it's rendered contains the
554 ``HttpRequest`` inside a ``request`` variable. This can be achieved by ensuring
555 the ``TEMPLATE_CONTEXT_PROCESSORS`` setting contains
556 ``"django.core.context_processors.request"``. By default it is not included,
557 and the setting itself is not even defined within your project's
558 ``settings.py``. To resolve this simply add the following to your
561 .. code-block:: python
563 TEMPLATE_CONTEXT_PROCESSORS = (
564 "django.contrib.auth.context_processors.auth",
565 "django.core.context_processors.debug",
566 "django.core.context_processors.i18n",
567 "django.core.context_processors.media",
568 "django.core.context_processors.static",
569 "django.contrib.messages.context_processors.messages",
570 "django.core.context_processors.request",
574 .. _template-tags.set_url_param:
579 This template tag is a utility that allows you to update a portion of the
580 query-string without overwriting the entire thing. However you shouldn't need
581 to use this template tag unless you are rendering the table from scratch (i.e.
582 not using ``as_html()`` or ``{% render_table %}``).
584 This is very useful if you want the give your users the ability to interact
585 with your table (e.g. change the ordering), because you will need to create
586 urls with the appropriate queries.
588 Let's assume we have the querystring ``?search=pirates&sort=name&page=5`` and
589 we want to update the ``sort`` parameter:
591 .. code-block:: django
593 {% set_url_param sort="dob" %} # ?search=pirates&sort=dob&page=5
594 {% set_url_param sort="" %} # ?search=pirates&page=5
595 {% set_url_param sort="" search="" %} # ?page=5
599 A table instance bound to data has two attributes ``columns`` and ``rows``,
600 which can be iterated over:
602 .. code-block:: django
607 {% for column in table.columns %}
608 <th><a href="?sort={{ column.name_toggled }}">{{ column }}</a></th>
613 {% for row in table.rows %}
615 {% for value in row %}
624 Class Based Generic Mixins
625 ==========================
627 Django 1.3 introduced `class based views`__ as a mechanism to reduce the
628 repetition in view code. django-tables2 comes with a single class based view
629 mixin: ``SingleTableMixin``. It makes it trivial to incorporate a table into a
630 view/template, however it requires a few variables to be defined on the view:
632 - ``table_class`` –- the table class to use, e.g. ``SimpleTable``
633 - ``table_data`` (or ``get_table_data()``) -- the data used to populate the
635 - ``context_table_name`` -- the name of template variable containing the table
638 .. __: https://docs.djangoproject.com/en/1.3/topics/class-based-views/
642 .. code-block:: python
644 from django_tables2.views import SingleTableMixin
645 from django.generic.views.list import ListView
648 class Simple(models.Model):
649 first_name = models.CharField(max_length=200)
650 last_name = models.CharField(max_length=200)
653 class SimpleTable(tables.Table):
654 first_name = tables.Column()
655 last_name = tables.Column()
658 class MyTableView(SingleTableMixin, ListView):
660 table_class = SimpleTable
663 The template could then be as simple as:
665 .. code-block:: django
667 {% load django_tables2 %}
668 {% render_table table %}
670 Such little code is possible due to the example above taking advantage of
671 default values and ``SimpleTableMixin``'s eagarness at finding data sources
672 when one isn't explicitly defined.
676 If you want more than one table on a page, at the moment the simplest way
677 to do it is to use ``SimpleTableMixin`` for one table, and write the
678 boilerplate for the other yourself in ``get_context_data()``. Obviously
679 this isn't particularly elegant, and as such will hopefully be resolved in
686 It's possible to create a mixin for a table that overrides something, however
687 unless it itself is a subclass of :class:`.Table` class
688 variable instances of :class:`.Column` will **not** be added to the class which is using the mixin.
692 >>> class UselessMixin(object):
693 ... extra = tables.Column()
695 >>> class TestTable(UselessMixin, tables.Table):
696 ... name = tables.Column()
698 >>> TestTable.base_columns.keys()
701 To have a mixin contribute a column, it needs to be a subclass of
702 :class:`~django_tables2.tables.Table`. With this in mind the previous example
703 *should* have been written as follows::
705 >>> class UsefulMixin(tables.Table):
706 ... extra = tables.Column()
708 >>> class TestTable(UsefulMixin, tables.Table):
709 ... name = tables.Column()
711 >>> TestTable.base_columns.keys()
718 Most of the time you'll probably be making tables to display queryset data, and
719 writing such tables involves a lot of duplicate code, e.g.::
721 >>> class Person(models.Model):
722 ... first_name = models.CharField(max_length=200)
723 ... last_name = models.CharField(max_length=200)
724 ... user = models.ForeignKey("auth.User")
725 ... dob = models.DateField()
727 >>> class PersonTable(tables.Table):
728 ... first_name = tables.Column()
729 ... last_name = tables.Column()
730 ... user = tables.Column()
731 ... dob = tables.Column()
734 Often a table will become quite complex after time, e.g. `table.render_foo`_,
735 changing ``verbose_name`` on columns, or adding an extra
736 :class:`~.CheckBoxColumn`.
738 ``django-tables2`` offers the :attr:`.Table.Meta.model` option to ease the pain.
739 The ``model`` option causes the table automatically generate columns for the
740 fields in the model. This means that the above table could be re-written as
743 >>> class PersonTable(tables.Table):
747 >>> PersonTable.base_columns.keys()
748 ['first_name', 'last_name', 'user', 'dob']
750 If you want to customise one of the columns, simply define it the way you would
753 >>> from django_tables2 import A
754 >>> class PersonTable(tables.Table):
755 ... user = tables.LinkColumn("admin:auth_user_change", args=[A("user.pk")])
760 >>> PersonTable.base_columns.keys()
761 ['first_name', 'last_name', 'dob', 'user']
763 It's not immediately obvious but if you look carefully you'll notice that the
764 order of the fields has now changed -- ``user`` is now last, rather than
765 ``dob``. This follows the same behaviour of Django's model forms, and can be
766 fixed in a similar way -- the :attr:`.Table.Meta.sequence` option::
768 >>> class PersonTable(tables.Table):
769 ... user = tables.LinkColumn("admin:auth_user_change", args=[A("user.pk")])
773 ... sequence = ("first_name", "last_name", "user", "dob")
775 >>> PersonTable.base_columns.keys()
776 ['first_name', 'last_name', 'user', 'dob']
778 … or use a shorter approach that makes use of the special ``"..."`` item::
780 >>> class PersonTable(tables.Table):
781 ... user = tables.LinkColumn("admin:auth_user_change", args=[A("user.pk")])
785 ... sequence = ("...", "dob")
787 >>> PersonTable.base_columns.keys()
788 ['first_name', 'last_name', 'user', 'dob']
794 :class:`Accessor` Objects:
795 --------------------------
797 .. autoclass:: django_tables2.utils.Accessor
801 :class:`Table` Objects:
802 -----------------------
804 .. autoclass:: django_tables2.tables.Table
807 :class:`Table.Meta` Objects:
808 ----------------------------
810 .. class:: Table.Meta
812 Provides a way to define *global* settings for table, as opposed to
813 defining them for each instance.
817 Allows custom HTML attributes to be specified which will be added to
818 the ``<table>`` tag of any table rendered via
819 :meth:`~django_tables2.tables.Table.as_html` or the
820 :ref:`template-tags.render_table` template tag.
825 This is typically used to enable a theme for a table (which is done by
826 adding a CSS class to the ``<table>`` element). i.e.::
828 class SimpleTable(tables.Table):
829 name = tables.Column()
832 attrs = {"class": "paleblue"}
836 This functionality is also available via the ``attrs`` keyword
837 argument to a table's constructor.
839 .. attribute:: empty_text
841 Defines the text to display when the table has no rows.
846 If the table is empty and ``bool(empty_text)`` is ``True``, a row is
847 displayed containing ``empty_text``. This is allows a message such as
848 *There are currently no FOO.* to be displayed.
852 This functionality is also available via the ``empty_text`` keyword
853 argument to a table's constructor.
855 .. attribute:: exclude
857 Defines which columns should be excluded from the table. This is useful
858 in subclasses to exclude columns in a parent.
860 :type: tuple of ``string`` objects
865 >>> class Person(tables.Table):
866 ... first_name = tables.Column()
867 ... last_name = tables.Column()
869 >>> Person.base_columns
870 {'first_name': <django_tables2.columns.Column object at 0x10046df10>,
871 'last_name': <django_tables2.columns.Column object at 0x10046d8d0>}
872 >>> class ForgetfulPerson(Person):
874 ... exclude = ("last_name", )
876 >>> ForgetfulPerson.base_columns
877 {'first_name': <django_tables2.columns.Column object at 0x10046df10>}
881 This functionality is also available via the ``exclude`` keyword
882 argument to a table's constructor.
884 However, unlike some of the other ``Meta`` options, providing the
885 ``exclude`` keyword to a table's constructor **won't override** the
886 ``Meta.exclude``. Instead, it will be effectively be *added*
887 to it. i.e. you can't use the constructor's ``exclude`` argument to
892 A model to inspect and automatically create corresponding columns.
897 This option allows a Django model to be specified to cause the table to
898 automatically generate columns that correspond to the fields in a
901 .. attribute:: order_by
903 The default ordering. e.g. ``('name', '-age')``. A hyphen ``-`` can be
904 used to prefix a column name to indicate *descending* order.
911 This functionality is also available via the ``order_by`` keyword
912 argument to a table's constructor.
914 .. attribute:: sequence
916 The sequence of the table columns. This allows the default order of
917 columns (the order they were defined in the Table) to be overridden.
919 :type: any iterable (e.g. ``tuple`` or ``list``)
922 The special item ``"..."`` can be used as a placeholder that will be
923 replaced with all the columns that weren't explicitly listed. This
924 allows you to add columns to the front or back when using inheritence.
928 >>> class Person(tables.Table):
929 ... first_name = tables.Column()
930 ... last_name = tables.Column()
933 ... sequence = ("last_name", "...")
935 >>> Person.base_columns.keys()
936 ['last_name', 'first_name']
938 The ``"..."`` item can be used at most once in the sequence value. If
939 it's not used, every column *must* be explicitly included. e.g. in the
940 above example, ``sequence = ("last_name", )`` would be **invalid**
941 because neither ``"..."`` or ``"first_name"`` were included.
945 This functionality is also available via the ``sequence`` keyword
946 argument to a table's constructor.
948 .. attribute:: sortable
950 Whether columns are by default sortable, or not. i.e. the fallback for
951 value for a column's sortable value.
956 If the ``Table`` and ``Column`` don't specify a value, a column's
957 ``sortable`` value will fallback to this. object specify. This provides
958 an easy mechanism to disable sorting on an entire table, without adding
959 ``sortable=False`` to each ``Column`` in a ``Table``.
963 This functionality is also available via the ``sortable`` keyword
964 argument to a table's constructor.
967 :class:`TableData` Objects:
968 ------------------------------
970 .. autoclass:: django_tables2.tables.TableData
971 :members: __init__, order_by, __getitem__, __len__
974 :class:`Column` Objects:
975 ------------------------
977 .. autoclass:: django_tables2.columns.Column
980 :class:`CheckBoxColumn` Objects:
981 --------------------------------
983 .. autoclass:: django_tables2.columns.CheckBoxColumn
987 :class:`LinkColumn` Objects:
988 ----------------------------
990 .. autoclass:: django_tables2.columns.LinkColumn
994 :class:`TemplateColumn` Objects:
995 --------------------------------
997 .. autoclass:: django_tables2.columns.TemplateColumn
1001 :class:`BoundColumns` Objects
1002 -----------------------------
1004 .. autoclass:: django_tables2.columns.BoundColumns
1005 :members: all, items, sortable, visible, __iter__,
1006 __contains__, __len__, __getitem__
1009 :class:`BoundColumn` Objects
1010 ----------------------------
1012 .. autoclass:: django_tables2.columns.BoundColumn
1016 :class:`BoundRows` Objects
1017 --------------------------
1019 .. autoclass:: django_tables2.rows.BoundRows
1020 :members: __iter__, __len__, count
1023 :class:`BoundRow` Objects
1024 -------------------------
1026 .. autoclass:: django_tables2.rows.BoundRow
1027 :members: __getitem__, __contains__, __iter__, record, table
1030 :class:`AttributeDict` Objects
1031 ------------------------------
1033 .. autoclass:: django_tables2.utils.AttributeDict
1037 :class:`OrderBy` Objects
1038 ------------------------
1040 .. autoclass:: django_tables2.utils.OrderBy
1044 :class:`OrderByTuple` Objects
1045 -----------------------------
1047 .. autoclass:: django_tables2.utils.OrderByTuple
1048 :members: __unicode__, __contains__, __getitem__, cmp
1057 Refers to an :class:`~django_tables2.utils.Accessor` object
1060 The non-prefixed form of an :class:`~django_tables2.utils.OrderBy`
1061 object. Typically the bare form is just the ascending form.
1063 Example: ``age`` is the bare form of ``-age``
1066 The name given to a column. In the follow example, the *column name* is
1069 .. code-block:: python
1071 class SimpleTable(tables.Table):
1072 age = tables.Column()
1075 The traditional concept of a table. i.e. a grid of rows and columns
1082 A single Python object used as the data for a single row.
1085 The act of serialising a :class:`~django_tables2.tables.Table` into
1092 An interable of :term:`records <record>` that
1093 :class:`~django_tables2.tables.Table` uses to populate its rows.