include README.rst
-recursive-include django_tables/templates *
-recursive-include django_tables/static *
+recursive-include django_tables2/templates *
+recursive-include django_tables2/static *
recursive-include example/app/fixtures *
recursive-include example/app/templates *
-===============================================
-django-tables - An app for creating HTML tables
-===============================================
+================================================
+django-tables2 - An app for creating HTML tables
+================================================
-django-tables simplifies the task of turning sets of datainto HTML tables. It
+.. note::
+
+ Prior to v0.6.0 this package was a fork of miracle2k's and both were known
+ as *django-tables*. This caused some problems (e.g. ambiguity and inability
+ to put this library on PyPI) so as of v0.6.0 this package is known as
+ *django-tables2*.
+
+django-tables2 simplifies the task of turning sets of data into HTML tables. It
has native support for pagination and sorting. It does for HTML tables what
``django.forms`` does for HTML forms.
-Documentation_ is available on http://readthedocs.org
+Creating a table is as simple as::
+
+ import django_tables2 as tables
+
+ class SimpleTable(tables.Table):
+ class Meta:
+ model = Simple
+
+This would then be used in a view::
+
+ def simple_list(request):
+ queryset = Simple.objects.all()
+ table = SimpleTable(queryset)
+ return render_to_response("simple_list.html", {"table": table},
+ context_instance=RequestContext(request))
+
+And finally in the template::
+
+ {% load django_tables2 %}
+ {% render_table table %}
+
+
+This example shows one of the simplest cases, but django-tables2 can do a lot
+more! Check out the `documentation`__ for more details.
-.. _Documentation: http://readthedocs.org/docs/django-tables/en/latest/
+.. __: http://readthedocs.org/docs/django-tables/en/latest/
Building the documentation
)
# tables.py
- from django_tables.utils import A # alias for Accessor
+ from django_tables2.utils import A # alias for Accessor
class PeopleTable(tables.Table):
name = tables.LinkColumn('people_detail', args=[A('pk')])
.. code-block:: python
- >>> import django_tables as tables
+ >>> import django_tables2 as tables
>>> class SimpleTable(tables.Table):
... a = tables.Column()
... b = tables.CheckBoxColumn(attrs={'name': 'my_chkbox'})
The rendered table won't include pagination or sorting, as those
features require a RequestContext. Use the ``render_table`` template
- tag (requires ``{% load django_tables %}``) if you require this extra
+ tag (requires ``{% load django_tables2 %}``) if you require this extra
functionality.
"""
- template = get_template('django_tables/basic_table.html')
+ template = get_template('django_tables2/basic_table.html')
return template.render(Context({'table': self}))
@property
{% spaceless %}
-{% load django_tables %}
+{% load django_tables2 %}
{% if table.page %}
<div class="table-container">
{% endif %}
-"""
+#! -*- coding: utf-8 -*-
+"""
Allows setting/changing/removing of chosen url query string parameters, while
maintaining any existing others.
"table": table})
try:
table.request = context["request"]
- return get_template("django_tables/table.html").render(context)
+ return get_template("django_tables2/table.html").render(context)
finally:
del table.request
except:
class OrderByTuple(tuple, StrAndUnicode):
"""Stores ordering as (as :class:`.OrderBy` objects). The
- :attr:`django_tables.tables.Table.order_by` property is always converted
+ :attr:`django_tables2.tables.Table.order_by` property is always converted
to an :class:`.OrderByTuple` object.
This class is essentially just a :class:`tuple` with some useful extras.
.. code-block:: python
- >>> from django_tables.utils import AttributeDict
+ >>> from django_tables2.utils import AttributeDict
>>> attrs = AttributeDict({'class': 'mytable', 'id': 'someid'})
>>> attrs.as_html()
'class="mytable" id="someid"'
``TemplateResponseMixin``.
:param table_class: table class
- :type table_class: subclass of ``django_tables.Table``
+ :type table_class: subclass of ``django_tables2.Table``
:param table_data: data used to populate the table
:type table_data: any compatible data source
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
- @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/django-tables.qhcp"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/django-tables2.qhcp"
@echo "To view the help file:"
- @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/django-tables.qhc"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/django-tables2.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
- @echo "# mkdir -p $$HOME/.local/share/devhelp/django-tables"
- @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/django-tables"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/django-tables2"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/django-tables2"
@echo "# devhelp"
epub:
# -*- coding: utf-8 -*-
#
-# django-tables documentation build configuration file, created by
+# django-tables2 documentation build configuration file, created by
# sphinx-quickstart on Wed Jan 5 13:04:34 2011.
#
# This file is execfile()d with the current directory set to its containing dir.
# import our libs
sys.path.insert(0, os.path.join(os.path.abspath('.'), os.pardir))
import example
-import django_tables as tables
+import django_tables2 as tables
sys.path.pop(0)
master_doc = 'index'
# General information about the project.
-project = u'django-tables'
+project = u'django-tables2'
#copyright = u''
# The version info for the project you're documenting, acts as replacement for
#html_file_suffix = None
# Output file base name for HTML help builder.
-htmlhelp_basename = 'django-tablesdoc'
+htmlhelp_basename = 'django-tables2doc'
# -- Options for LaTeX output --------------------------------------------------
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
- ('index', 'django-tables.tex', u'django-tables Documentation',
+ ('index', 'django-tables2.tex', u'django-tables2 Documentation',
u'n/a', 'manual'),
]
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
- ('index', 'django-tables', u'django-tables Documentation',
+ ('index', 'django-tables2', u'django-tables2 Documentation',
[u'n/a'], 1)
]
.. default-domain:: py
-===============================================
-django-tables - An app for creating HTML tables
-===============================================
+================================================
+django-tables2 - An app for creating HTML tables
+================================================
-django-tables simplifies the task of turning sets of datainto HTML tables. It
+django-tables2 simplifies the task of turning sets of datainto HTML tables. It
has native support for pagination and sorting. It does for HTML tables what
``django.forms`` does for HTML forms.
Quick start guide
=================
-1. Download and install from https://github.com/bradleyayers/django-tables.
+1. Download and install from https://github.com/bradleyayers/django-tables2.
Grab a ``.tar.gz`` of the latest tag, and run ``pip install <tar.gz>``.
-2. Hook the app into your Django project by adding ``'django_tables'`` to your
+2. Hook the app into your Django project by adding ``'django_tables2'`` to your
``INSTALLED_APPS`` setting.
-3. Write a subclass of :class:`~django_tables.tables.Table` that describes the
+3. Write a subclass of :class:`~django_tables2.tables.Table` that describes the
structure of your table.
4. Create an instance of your table in a :term:`view`, provide it with
:term:`table data`, and pass it to a :term:`template` for display.
]
-The first step is to subclass :class:`~django_tables.tables.Table` and describe
+The first step is to subclass :class:`~django_tables2.tables.Table` and describe
the table structure. This is done by creating a column for each attribute in
the :term:`table data`.
.. code-block:: python
- import django_tables as tables
+ import django_tables2 as tables
class CountryTable(tables.Table):
name = tables.Column()
context_instance=RequestContext(request))
In your template, the easiest way to :term:`render` the table is via the
-:meth:`~django_tables.tables.Table.as_html` method:
+:meth:`~django_tables2.tables.Table.as_html` method:
.. code-block:: django
.. code-block:: django
- {% load django_tables %}
+ {% load django_tables2 %}
{% render_table table %}
.. note::
.. code-block:: python
- import django_tables as tables
+ import django_tables2 as tables
class CountryTable(tables.Table):
name = tables.Column()
.. code-block:: html
- <link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}django_tables/themes/paleblue/css/screen.css" />
+ <link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}django_tables2/themes/paleblue/css/screen.css" />
Save your template and reload the page in your browser.
Each item in the :term:`table data` is called a :term:`record` and is used to
populate a single row in the table. By default, the table uses column names
as :term:`accessors <accessor>` to retrieve individual cell values. This can
-be changed via the :attr:`~django_tables.columns.Column.accessor` argument.
+be changed via the :attr:`~django_tables2.columns.Column.accessor` argument.
Any iterable can be used as table data, and there's builtin support for
:class:`QuerySet` objects (to ensure they're handled effeciently).
==============
The header cell for each column comes from the column's
-:meth:`~django_tables.columns.BoundColumn.header` method. By default this
+:meth:`~django_tables2.columns.BoundColumn.header` method. By default this
method returns the column's ``verbose_name``, which is either explicitly
specified, or generated automatically based on the column name.
---
In order to use CSS to style a table, you'll probably want to add a
-``class`` or ``id`` attribute to the ``<table>`` element. ``django-tables`` has
+``class`` or ``id`` attribute to the ``<table>`` element. ``django-tables2`` has
a hook that allows abitrary attributes to be added to the ``<table>`` tag.
.. code-block:: python
- >>> import django_tables as tables
+ >>> import django_tables2 as tables
>>> class SimpleTable(tables.Table):
... id = tables.Column()
... age = tables.Column()
.. code-block:: python
- >>> import django_tables as tables
+ >>> import django_tables2 as tables
>>> class SimpleTable(tables.Table):
... row_number = tables.Column()
... id = tables.Column()
.. code-block:: python
- >>> import django_tables as tables
+ >>> import django_tables2 as tables
>>>
>>> class AngryColumn(tables.Column):
... def render(self, value):
.. code-block:: django
- {% load django_tables %}
+ {% load django_tables2 %}
<table>
<thead>
<tr>
render_table
------------
-Renders a :class:`~django_tables.tables.Table` object to HTML and includes as
+Renders a :class:`~django_tables2.tables.Table` object to HTML and includes as
many features as possible.
Sample usage:
.. code-block:: django
- {% load django_tables %}
+ {% load django_tables2 %}
{% render_table table %}
This tag temporarily modifies the :class:`.Table` object while it is being
==========================
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
+repetition in view code. django-tables2 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:
.. code-block:: python
- from django_tables.views import SingleTableMixin
+ from django_tables2.views import SingleTableMixin
from django.generic.views.list import ListView
.. code-block:: django
- {% load django_tables %}
+ {% load django_tables2 %}
{% render_table table %}
Such little code is possible due to the example above taking advantage of
['name']
To have a mixin contribute a column, it needs to be a subclass of
-:class:`~django_tables.tables.Table`. With this in mind the previous example
+:class:`~django_tables2.tables.Table`. With this in mind the previous example
*should* have been written as follows::
>>> class UsefulMixin(tables.Table):
changing ``verbose_name`` on columns, or adding an extra
:class:`~.CheckBoxColumn`.
-``django-tables`` offers the :attr:`.Table.Meta.model` option to ease the pain.
+``django-tables2`` offers the :attr:`.Table.Meta.model` option to ease the pain.
The ``model`` option causes the table automatically generate columns for the
fields in the model. This means that the above table could be re-written as
follows::
If you want to customise one of the columns, simply define it the way you would
normally::
- >>> from django_tables import A
+ >>> from django_tables2 import A
>>> class PersonTable(tables.Table):
... user = tables.LinkColumn("admin:auth_user_change", args=[A("user.pk")])
...
:class:`Accessor` Objects:
--------------------------
-.. autoclass:: django_tables.utils.Accessor
+.. autoclass:: django_tables2.utils.Accessor
:members:
:class:`Table` Objects:
-----------------------
-.. autoclass:: django_tables.tables.Table
+.. autoclass:: django_tables2.tables.Table
:class:`Table.Meta` Objects:
Allows custom HTML attributes to be specified which will be added to
the ``<table>`` tag of any table rendered via
- :meth:`~django_tables.tables.Table.as_html` or the
+ :meth:`~django_tables2.tables.Table.as_html` or the
:ref:`template-tags.render_table` template tag.
:type: ``dict``
... last_name = tables.Column()
...
>>> Person.base_columns
- {'first_name': <django_tables.columns.Column object at 0x10046df10>,
- 'last_name': <django_tables.columns.Column object at 0x10046d8d0>}
+ {'first_name': <django_tables2.columns.Column object at 0x10046df10>,
+ 'last_name': <django_tables2.columns.Column object at 0x10046d8d0>}
>>> class ForgetfulPerson(Person):
... class Meta:
... exclude = ("last_name", )
...
>>> ForgetfulPerson.base_columns
- {'first_name': <django_tables.columns.Column object at 0x10046df10>}
+ {'first_name': <django_tables2.columns.Column object at 0x10046df10>}
.. note::
:class:`TableData` Objects:
------------------------------
-.. autoclass:: django_tables.tables.TableData
+.. autoclass:: django_tables2.tables.TableData
:members: __init__, order_by, __getitem__, __len__
:class:`Column` Objects:
------------------------
-.. autoclass:: django_tables.columns.Column
+.. autoclass:: django_tables2.columns.Column
:class:`CheckBoxColumn` Objects:
--------------------------------
-.. autoclass:: django_tables.columns.CheckBoxColumn
+.. autoclass:: django_tables2.columns.CheckBoxColumn
:members:
:class:`LinkColumn` Objects:
----------------------------
-.. autoclass:: django_tables.columns.LinkColumn
+.. autoclass:: django_tables2.columns.LinkColumn
:members:
:class:`TemplateColumn` Objects:
--------------------------------
-.. autoclass:: django_tables.columns.TemplateColumn
+.. autoclass:: django_tables2.columns.TemplateColumn
:members:
:class:`BoundColumns` Objects
-----------------------------
-.. autoclass:: django_tables.columns.BoundColumns
+.. autoclass:: django_tables2.columns.BoundColumns
:members: all, items, sortable, visible, __iter__,
__contains__, __len__, __getitem__
:class:`BoundColumn` Objects
----------------------------
-.. autoclass:: django_tables.columns.BoundColumn
+.. autoclass:: django_tables2.columns.BoundColumn
:members:
:class:`BoundRows` Objects
--------------------------
-.. autoclass:: django_tables.rows.BoundRows
+.. autoclass:: django_tables2.rows.BoundRows
:members: __iter__, __len__, count
:class:`BoundRow` Objects
-------------------------
-.. autoclass:: django_tables.rows.BoundRow
+.. autoclass:: django_tables2.rows.BoundRow
:members: __getitem__, __contains__, __iter__, record, table
:class:`AttributeDict` Objects
------------------------------
-.. autoclass:: django_tables.utils.AttributeDict
+.. autoclass:: django_tables2.utils.AttributeDict
:members:
:class:`OrderBy` Objects
------------------------
-.. autoclass:: django_tables.utils.OrderBy
+.. autoclass:: django_tables2.utils.OrderBy
:members:
:class:`OrderByTuple` Objects
-----------------------------
-.. autoclass:: django_tables.utils.OrderByTuple
+.. autoclass:: django_tables2.utils.OrderByTuple
:members: __unicode__, __contains__, __getitem__, cmp
.. glossary::
accessor
- Refers to an :class:`~django_tables.utils.Accessor` object
+ Refers to an :class:`~django_tables2.utils.Accessor` object
bare orderby
- The non-prefixed form of an :class:`~django_tables.utils.OrderBy`
+ The non-prefixed form of an :class:`~django_tables2.utils.OrderBy`
object. Typically the bare form is just the ascending form.
Example: ``age`` is the bare form of ``-age``
A single Python object used as the data for a single row.
render
- The act of serialising a :class:`~django_tables.tables.Table` into
+ The act of serialising a :class:`~django_tables2.tables.Table` into
HTML.
template
table data
An interable of :term:`records <record>` that
- :class:`~django_tables.tables.Table` uses to populate its rows.
+ :class:`~django_tables2.tables.Table` uses to populate its rows.
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
- echo.^> qcollectiongenerator %BUILDDIR%\qthelp\django-tables.qhcp
+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\django-tables2.qhcp
echo.To view the help file:
- echo.^> assistant -collectionFile %BUILDDIR%\qthelp\django-tables.ghc
+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\django-tables2.ghc
goto end
)
-import django_tables as tables
+import django_tables2 as tables
class CountryTable(tables.Table):
-# import django_tables
+# import django_tables2
from os.path import dirname, join, abspath
import sys
'django.contrib.messages',
'django.contrib.staticfiles',
'example.app',
- 'django_tables',
+ 'django_tables2',
)
# A sample logging configuration. The only tangible logging
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="{{ LANGUAGE_CODE }}" xml:lang="{{ LANGUAGE_CODE }}">
<head>
- <title>django-tables examples</title>
- <link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}django_tables/themes/paleblue/css/screen.css" />
+ <title>django-tables2 examples</title>
+ <link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}django_tables2/themes/paleblue/css/screen.css" />
<style type="text/css">
pre {
background-color: #D8F0FF;
</head>
<body>
- <h1><tt>django-tables</tt> examples</h1>
+ <h1><tt>django-tables2</tt> examples</h1>
<p>This page demonstrates various types of tables being rendered via
- <tt>django-tables</tt>.</p>
+ <tt>django-tables2</tt>.</p>
<h2>Example 1 — QuerySet</h2>
<h3>via <tt>as_html()</tt></h3>
{{ example1.as_html }}
<h3>via template tag</h3>
- <pre>{% templatetag openblock %} load django_tables {% templatetag closeblock %}
+ <pre>{% templatetag openblock %} load django_tables2 {% templatetag closeblock %}
{% templatetag openblock %} render_table example1 {% templatetag closeblock %}</pre>
- {% load django_tables %}
+ {% load django_tables2 %}
{% render_table example1 %}
<h2>Example 2 — QuerySet + pagination</h2>
{{ example2.as_html }}
<h3>via template tag</h3>
- <pre>{% templatetag openblock %} load django_tables {% templatetag closeblock %}
+ <pre>{% templatetag openblock %} load django_tables2 {% templatetag closeblock %}
{% templatetag openblock %} render_table example2 {% templatetag closeblock %}</pre>
- {% load django_tables %}
+ {% load django_tables2 %}
{% render_table example2 %}
<h2>Example 3 — QuerySet + paleblue theme</h2>
{{ example3.as_html }}
<h3>via template tag</h3>
- <pre>{% templatetag openblock %} load django_tables {% templatetag closeblock %}
+ <pre>{% templatetag openblock %} load django_tables2 {% templatetag closeblock %}
{% templatetag openblock %} render_table example3 {% templatetag closeblock %}</pre>
- {% load django_tables %}
+ {% load django_tables2 %}
{% render_table example3 %}
<h2>Example 4 — QuerySet + pagination + paleblue theme</h2>
{{ example4.as_html }}
<h3>via template tag</h3>
- <pre>{% templatetag openblock %} load django_tables {% templatetag closeblock %}
+ <pre>{% templatetag openblock %} load django_tables2 {% templatetag closeblock %}
{% templatetag openblock %} render_table example4 {% templatetag closeblock %}</pre>
- {% load django_tables %}
+ {% load django_tables2 %}
{% render_table example4 %}
</body>
setup(
- name='django-tables',
- version='0.5.1',
+ name='django-tables2',
+ version='0.6.0.dev',
description='Table framework for Django',
author='Bradley Ayers',
author_email='bradley.ayers@gmail.com',
license='Simplified BSD',
- url='https://github.com/bradleyayers/django-tables/',
+ url='https://github.com/bradleyayers/django-tables2/',
packages=find_packages(exclude=['tests.*', 'tests', 'example.*', 'example']),
include_package_data=True, # declarations in MANIFEST.in
},
INSTALLED_APPS = [
'tests.testapp',
- 'django_tables',
+ 'django_tables2',
],
ROOT_URLCONF = 'tests.testapp.urls',
)
from django.test.client import RequestFactory
from django.template import Context, Template
from django.core.exceptions import ImproperlyConfigured
-import django_tables as tables
-from django_tables import utils, A
+import django_tables2 as tables
+from django_tables2 import utils, A
from .testapp.models import Person
table = UnicodeTable(dataset)
request = RequestFactory().get('/some-url/')
- template = Template('{% load django_tables %}{% render_table table %}')
+ template = Template('{% load django_tables2 %}{% render_table table %}')
html = template.render(Context({'request': request, 'table': table}))
Assert(u'Brädley' in html)
from attest import Tests, Assert
from django.http import Http404
from django.core.paginator import Paginator
-import django_tables as tables
-from django_tables import utils
+import django_tables2 as tables
+from django_tables2 import utils
core = Tests()
from django.conf import settings
from django.test.client import RequestFactory
from django.template import Template, Context
-import django_tables as tables
+import django_tables2 as tables
from django_attest import TransactionTestContext
from attest import Tests, Assert
from .testapp.models import Person, Occupation
"""Test the core table functionality."""
from attest import Tests, Assert
-import django_tables as tables
-from django_tables import utils
+import django_tables2 as tables
+from django_tables2 import utils
rows = Tests()
from django.template import Template, Context, VariableDoesNotExist
from django.http import HttpRequest
from django.conf import settings
-import django_tables as tables
+import django_tables2 as tables
from attest import Tests, Assert
from xml.etree import ElementTree as ET
def templatetag():
# ensure it works with a multi-order-by
table = CountryTable(MEMORY_DATA, order_by=('name', 'population'))
- t = Template('{% load django_tables %}{% render_table table %}')
+ t = Template('{% load django_tables2 %}{% render_table table %}')
html = t.render(Context({'request': HttpRequest(), 'table': table}))
root = ET.fromstring(html)
# no data with no empty_text
table = CountryTable([])
- t = Template('{% load django_tables %}{% render_table table %}')
+ t = Template('{% load django_tables2 %}{% render_table table %}')
html = t.render(Context({'request': HttpRequest(), 'table': table}))
root = ET.fromstring(html)
Assert(len(root.findall('.//thead/tr'))) == 1
# no data WITH empty_text
table = CountryTable([], empty_text='this table is empty')
- t = Template('{% load django_tables %}{% render_table table %}')
+ t = Template('{% load django_tables2 %}{% render_table table %}')
html = t.render(Context({'request': HttpRequest(), 'table': table}))
root = ET.fromstring(html)
Assert(len(root.findall('.//thead/tr'))) == 1
Assert(root.find('.//tbody/tr/td').text) == 'this table is empty'
# variable that doesn't exist (issue #8)
- t = Template('{% load django_tables %}{% render_table this_doesnt_exist %}')
+ t = Template('{% load django_tables2 %}{% render_table this_doesnt_exist %}')
with Assert.raises(VariableDoesNotExist):
settings.DEBUG = True
t.render(Context())
# -*- coding: utf8 -*-
-from django_tables.utils import OrderByTuple, OrderBy, Accessor
+from django_tables2.utils import OrderByTuple, OrderBy, Accessor
from attest import Tests, Assert