[Python-modules-commits] [django-tables] 01/07: Import django-tables_1.2.0.orig.tar.gz
Brian May
bam at moszumanska.debian.org
Tue May 3 01:55:24 UTC 2016
This is an automated email from the git hooks/post-receive script.
bam pushed a commit to branch master
in repository django-tables.
commit ef66a89cc2badd78e4e67573e6bfc23c221e6095
Author: Brian May <bam at debian.org>
Date: Tue May 3 10:37:15 2016 +1000
Import django-tables_1.2.0.orig.tar.gz
---
CHANGELOG.md | 19 +-
CONTRIBUTING.md | 44 ++++
README.rst | 39 +---
django_tables2/__init__.py | 2 +-
django_tables2/columns/emailcolumn.py | 16 +-
django_tables2/columns/linkcolumn.py | 54 ++---
django_tables2/columns/urlcolumn.py | 18 +-
django_tables2/config.py | 7 +-
django_tables2/locale/en/LC_MESSAGES/django.mo | Bin 392 -> 606 bytes
django_tables2/locale/en/LC_MESSAGES/django.po | 31 ++-
django_tables2/locale/it/LC_MESSAGES/django.mo | Bin 0 -> 762 bytes
django_tables2/locale/it/LC_MESSAGES/django.po | 45 ++++
django_tables2/locale/nl/LC_MESSAGES/django.mo | Bin 0 -> 776 bytes
django_tables2/locale/nl/LC_MESSAGES/django.po | 45 ++++
django_tables2/rows.py | 93 +++++----
django_tables2/tables.py | 72 ++++---
.../templates/django_tables2/bootstrap.html | 6 +-
django_tables2/templates/django_tables2/table.html | 6 +-
django_tables2/utils.py | 77 +++++--
django_tables2/views.py | 29 ++-
docs/index.rst | 8 +-
docs/pages/accessors.rst | 7 +-
docs/pages/api-reference.rst | 46 +++--
docs/pages/column-attributes.rst | 12 +-
docs/pages/column-headers.rst | 19 +-
docs/pages/custom-rendering.rst | 22 +-
docs/pages/generic-mixins.rst | 10 +-
docs/pages/glossary.rst | 2 +-
docs/pages/internal.rst | 3 +-
docs/pages/localization-control.rst | 3 -
docs/pages/order-by-accessors.rst | 15 +-
docs/pages/pagination.rst | 9 +-
docs/pages/query-string-fields.rst | 11 +-
docs/pages/swapping-columns.rst | 6 +-
docs/pages/table-data.rst | 7 +-
docs/pages/tables-for-models.rst | 2 +-
docs/pages/template-filters.rst | 2 +-
docs/pages/template-tags.rst | 13 +-
docs/pages/tutorial.rst | 2 +-
docs/pages/upgrading-from-v1.rst | 10 +-
setup.py | 2 +-
tests/app/urls.py | 9 +-
tests/columns/test_booleancolumn.py | 30 +--
tests/columns/test_checkboxcolumn.py | 59 ++++--
tests/columns/test_datecolumn.py | 39 ++--
tests/columns/test_datetimecolumn.py | 44 ++--
tests/columns/test_emailcolumn.py | 28 +--
tests/columns/test_filecolumn.py | 3 +-
tests/columns/test_general.py | 150 +++++++-------
tests/columns/test_linkcolumn.py | 51 +++--
tests/columns/test_templatecolumn.py | 31 +--
tests/columns/test_timecolumn.py | 11 +-
tests/columns/test_urlcolumn.py | 34 ++-
tests/test_core.py | 228 +++++++++++++--------
tests/test_models.py | 34 +--
tests/test_rows.py | 16 +-
tests/test_templates.py | 22 ++
tests/test_utils.py | 110 ++++++++--
tests/test_views.py | 71 +++++--
59 files changed, 1131 insertions(+), 653 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e34e9f9..7188759 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,24 @@
# Change log
-## v1.1.5 (2016-04-02)
+## v1.2.0 (2016-05-02)
+- Allow custom attributes for rows (fixes #47)
+
+## v1.1.8 (2016-05-02)
+- Pass the table instance into `SingleTableMixin.get_table_pagination()` (#320 by
+(@georgema1982)[https://github.com/georgema1982])
+- Ability to change the body of the `<a>`-tag, by passing `text` kwarg to the columns inheriting from BaseLinkColumn (#318 by [@desecho](https://github.com/desecho), #322)
+- Non-field based LinkColumn only renders default value if lookup fails and text is not set. (#322, fixes #257)
+
+## v1.1.7 (2016-04-26)
+- Added Italian translation (#315 by [@paolodina](https://github.com/paolodina)
+- Added Dutch translation.
+- Fixed {% blocktrans %} template whitespace issues
+- Fixed errors when using a column named `items` (#316)
+- Obey `paginate_by` (from `MultipleObjectMixin`) if no later pagination is defined (#242)
+
+## v1.1.6 (2016-04-02)
- Correct error message about request context processors for current Django (#314)
+- Skipped 1.1.5 due to an error while creating the tag.
## v1.1.4 (2016-03-22)
- Fix broken `setup.py` if Django is not installed before django-tables2 (fixes #312)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..d8f22b1
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,44 @@
+# Contributing to django-tables2
+
+You are welcome to contribute to the development of `django-tables2` in various ways:
+
+- Discover and [report bugs](https://github.com/bradleyayers/django-tables2/issues/new).
+ Make sure to include a minimal example to show your problem.
+- Propose features or fix bugs by [opening a Pull Request](https://github.com/bradleyayers/django-tables2/compare)
+- Fix documenation or translations
+
+When contributing code or making bug fixes, we need to have unit tests to verify the expected behaviour.
+
+## Running the tests
+
+With `tox` installed, you can run the test suite by typing `tox`.
+It will take care of installing the correct dependencies. During development,
+you might not want to wait for the tests to run in all environments.
+In that case, use the `-e` argument to specify an environment:
+`tox -e py27-1.9` to run the tests in python 2.7 with Django 1.9,
+or `PYTHONPATH=. py.test` to run the tests against your current environment (which is even quicker).
+
+## Code coverage
+
+To generate a html coverage report:
+```
+PYTHONPATH=. py.test -s --cov=django_tables2 --cov-report html
+```
+
+## Building the documentation
+
+If you want to build the docs from within a virtualenv, and Sphinx is installed
+globally, use:
+
+```
+cd docs/
+make html SPHINXBUILD="python $(which sphinx-build)"
+```
+
+Publishing a release
+--------------------
+
+1. Bump the version in `django-tables2/__init__.py`.
+2. Update CHANGELOG.md`.
+3. Create a tag git tag -a v1.0.6 -m 'tagging v1.0.6'`
+4. Run `python setup.py sdist upload --sign --identity=<your gpg identity>`.
diff --git a/README.rst b/README.rst
index bec4686..e0d64dd 100644
--- a/README.rst
+++ b/README.rst
@@ -34,7 +34,7 @@ Its features include:
Example
-------
-Start by adding "django_tables2" to your INSTALLED_APPS setting like this:
+Start by adding ``django_tables2`` to your ``INSTALLED_APPS`` setting like this:
.. code:: python
@@ -69,38 +69,5 @@ 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: http://django-tables2.readthedocs.org/en/latest/ for more details.
-
-Running the tests
------------------
-
-With ``tox`` installed, you can run the test suite by typing ``tox``. It will take
-care of installing the correct dependencies. During development, you might not
-want to wait for the tests to run in all environments. In that case, use the ``-e``
-argument to specify an environment:
-
-``tox -e py27-1.9`` to run the tests in python 2.7 with Django 1.9.
-
-To generate a html coverage report:
-
- PYTHONPATH=. py.test -s --cov=django_tables2 --cov-report html
-
-
-Building the documentation
---------------------------
-
-If you want to build the docs from within a virtualenv, and Sphinx is installed
-globally, use:
-
- cd docs/
- make html SPHINXBUILD="python $(which sphinx-build)"
-
-
-Publishing a release
---------------------
-
-1. Bump the version in ``django-tables2/__init__.py``.
-2. Update ``CHANGELOG.md``.
-3. Create a tag ``git tag -a v1.0.6 -m 'tagging v1.0.6'``
-4. Run ``python setup.py sdist upload --sign --identity=<your gpg identity>``.
+This example shows one of the simplest cases, but django-tables2 can do a lot more!
+Check out the _documentation: http://django-tables2.readthedocs.org/en/latest/ for more details.
diff --git a/django_tables2/__init__.py b/django_tables2/__init__.py
index bd7b4f5..88962c7 100644
--- a/django_tables2/__init__.py
+++ b/django_tables2/__init__.py
@@ -8,4 +8,4 @@ from .utils import A
from .views import SingleTableMixin, SingleTableView
-__version__ = "1.1.6"
+__version__ = '1.2.0'
diff --git a/django_tables2/columns/emailcolumn.py b/django_tables2/columns/emailcolumn.py
index b6804f8..be164bd 100644
--- a/django_tables2/columns/emailcolumn.py
+++ b/django_tables2/columns/emailcolumn.py
@@ -12,10 +12,12 @@ class EmailColumn(BaseLinkColumn):
"""
A subclass of `.BaseLinkColumn` that renders the cell value as a hyperlink.
- It's common to have a email value in a row hyperlinked to other page.
+ It's common to have a email value in a row hyperlinked to another page.
- :param attrs: a `dict` of HTML attributes that are added to
- the rendered ``<a href="...">...</a>`` tag
+ :param attrs: a `dict` of HTML attributes that are added to the rendered
+ ``<a href="...">...</a>`` tag
+ :param text: Either static text, or a callable. If set, this value will be
+ used to render the text inside link instead of value (default)
Example:
@@ -32,8 +34,12 @@ class EmailColumn(BaseLinkColumn):
email = tables.EmailColumn()
"""
- def render(self, value):
- return self.render_link('mailto:%s' % value, text=value)
+ def render(self, record, value):
+ return self.render_link(
+ uri='mailto:{}'.format(value),
+ record=record,
+ value=value
+ )
@classmethod
def from_field(cls, field):
diff --git a/django_tables2/columns/linkcolumn.py b/django_tables2/columns/linkcolumn.py
index 2e3488c..37304ac 100644
--- a/django_tables2/columns/linkcolumn.py
+++ b/django_tables2/columns/linkcolumn.py
@@ -13,20 +13,29 @@ class BaseLinkColumn(Column):
"""
The base for other columns that render links.
- Adds support for an ``a`` key in *attrs** which is added to the rendered
- ``<a href="...">`` tag.
+ :param text: Either static text, or a callable. If set, this value will be
+ used to render the text inside link instead of value (default).
+ The calleble gets the record being rendered as argument.
+ :param attrs: Additional attributes for the ``<a>`` tag
"""
- def __init__(self, attrs=None, *args, **kwargs):
+ def __init__(self, attrs=None, text=None, *args, **kwargs):
kwargs['attrs'] = attrs
+ self.text = text
super(BaseLinkColumn, self).__init__(*args, **kwargs)
- def render_link(self, uri, text, attrs=None):
+ def text_value(self, record, value):
+ if self.text is None:
+ return value
+ return self.text(record) if callable(self.text) else self.text
+
+ def render_link(self, uri, record, value, attrs=None):
"""
Render a hyperlink.
- :param uri: URI for the hyperlink
- :param text: value wrapped in ``<a></a>``
- :param attrs: ``<a>`` tag attributes
+ :param uri: URI for the hyperlink
+ :param record: record currently being rendered
+ :param value: value wrapped in ``<a></a>``, might be overridden by ``self.text``
+ :param attrs: ``<a>`` tag attributes
"""
attrs = AttributeDict(attrs if attrs is not None else
self.attrs.get('a', {}))
@@ -35,7 +44,7 @@ class BaseLinkColumn(Column):
return format_html(
'<a {attrs}>{text}</a>',
attrs=attrs.as_html(),
- text=text
+ text=self.text_value(record, value)
)
@@ -60,11 +69,12 @@ class LinkColumn(BaseLinkColumn):
:param args: See `~django.core.urlresolvers.reverse`. **
:param kwargs: See `~django.core.urlresolvers.reverse`. **
:param current_app: See `~django.core.urlresolvers.reverse`.
- :param attrs: a `dict` of HTML attributes that are added to
- the rendered ``<input type="checkbox" .../>`` tag
- :param text: Either static text, or a callable. If set, this
- value will be used to render the text inside link
- instead of value (default)
+ :param attrs: a `dict` of HTML attributes that are added to the
+ rendered ``<a ...>...</a>`` tag.
+ :param text: Either static text, or a callable. If set, this value
+ will be used to render the text inside link instead of
+ value (default).
+ The calleble gets the record being rendered as argument.
** In order to create a link to a URL that relies on information in the
current row, `.Accessor` objects can be used in the *args* or
@@ -112,14 +122,13 @@ class LinkColumn(BaseLinkColumn):
- *a* -- ``<a>`` elements in ``<td>``.
"""
def __init__(self, viewname=None, urlconf=None, args=None, kwargs=None,
- current_app=None, attrs=None, text=None, **extra):
+ current_app=None, attrs=None, **extra):
super(LinkColumn, self).__init__(attrs, **extra)
self.viewname = viewname
self.urlconf = urlconf
self.args = args
self.kwargs = kwargs
self.current_app = current_app
- self.text_value = text
def compose_url(self, record, *args, **kwargs):
'''Compose the url if the column is constructed with a viewname.'''
@@ -148,19 +157,18 @@ class LinkColumn(BaseLinkColumn):
return reverse(viewname, **params)
def render(self, value, record, bound_column):
- text_value = value
- if self.text_value:
- text_value = self.text_value
- if callable(text_value):
- text_value = text_value(record)
-
- return self.render_link(self.compose_url(record, bound_column), text=text_value)
+ return self.render_link(
+ self.compose_url(record, bound_column),
+ record=record,
+ value=value
+ )
@library.register
class RelatedLinkColumn(LinkColumn):
'''
- Render a link to a related object using related object's ``get_absolute_url``
+ Render a link to a related object using related object's ``get_absolute_url``,
+ same parameters as ``LinkColumn``
'''
def compose_url(self, record, bound_column):
diff --git a/django_tables2/columns/urlcolumn.py b/django_tables2/columns/urlcolumn.py
index 1ed7fd6..958c2f4 100644
--- a/django_tables2/columns/urlcolumn.py
+++ b/django_tables2/columns/urlcolumn.py
@@ -1,6 +1,8 @@
# coding: utf-8
from __future__ import absolute_import, unicode_literals
+
from django.db import models
+
from .base import library
from .linkcolumn import BaseLinkColumn
@@ -10,21 +12,23 @@ class URLColumn(BaseLinkColumn):
"""
Renders URL values as hyperlinks.
+ :param text: Either static text, or a callable. If set, this
+ value will be used to render the text inside link
+ instead of value (default)
+ :param attrs: Additional attributes for the ``<a>`` tag
+
Example::
>>> class CompaniesTable(tables.Table):
... www = tables.URLColumn()
...
- >>> table = CompaniesTable([{"www": "http://google.com"}])
- >>> table.rows[0]["www"]
+ >>> table = CompaniesTable([{'www': 'http://google.com'}])
+ >>> table.rows[0].get_cell('www')
u'<a href="http://google.com">http://google.com</a>'
- Additional attributes for the ``<a>`` tag can be specified via
- ``attrs['a']``.
-
"""
- def render(self, value):
- return self.render_link(value, value)
+ def render(self, record, value):
+ return self.render_link(value, record=record, value=value)
@classmethod
def from_field(cls, field):
diff --git a/django_tables2/config.py b/django_tables2/config.py
index 8c548aa..4348a5b 100644
--- a/django_tables2/config.py
+++ b/django_tables2/config.py
@@ -1,5 +1,6 @@
# coding: utf-8
from __future__ import unicode_literals
+
from django.core.paginator import EmptyPage, PageNotAnInteger
@@ -37,13 +38,13 @@ class RequestConfig(object):
if order_by:
table.order_by = order_by
if self.paginate:
- if hasattr(self.paginate, "items"):
+ if hasattr(self.paginate, 'items'):
kwargs = dict(self.paginate)
else:
kwargs = {}
# extract some options from the request
- for arg in ("page", "per_page"):
- name = getattr(table, "prefixed_%s_field" % arg)
+ for arg in ('page', 'per_page'):
+ name = getattr(table, 'prefixed_%s_field' % arg)
try:
kwargs[arg] = int(self.request.GET[name])
except (ValueError, KeyError):
diff --git a/django_tables2/locale/en/LC_MESSAGES/django.mo b/django_tables2/locale/en/LC_MESSAGES/django.mo
index 030119f..8468d9b 100644
Binary files a/django_tables2/locale/en/LC_MESSAGES/django.mo and b/django_tables2/locale/en/LC_MESSAGES/django.mo differ
diff --git a/django_tables2/locale/en/LC_MESSAGES/django.po b/django_tables2/locale/en/LC_MESSAGES/django.po
index b446f74..7e74f77 100644
--- a/django_tables2/locale/en/LC_MESSAGES/django.po
+++ b/django_tables2/locale/en/LC_MESSAGES/django.po
@@ -4,7 +4,7 @@ msgid ""
msgstr ""
"Project-Id-Version: django-tables2\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-09-18 03:12+0200\n"
+"POT-Creation-Date: 2016-04-19 10:22+0200\n"
"PO-Revision-Date: 2011-11-06 10:41+1000\n"
"Last-Translator: Bradley Ayers <bradley.ayers at gmail.com>\n"
"Language-Team: English <en at li.org>\n"
@@ -13,20 +13,35 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: templates/django_tables2/table.html:55
-msgid "Previous"
+#: templates/django_tables2/bootstrap.html:35
+msgid "no results"
msgstr ""
-#: templates/django_tables2/table.html:59
+#: templates/django_tables2/bootstrap.html:55
+#, fuzzy
+#| msgid "Previous"
+msgid "previous"
+msgstr "Previous"
+
+#: templates/django_tables2/bootstrap.html:59
+#: templates/django_tables2/table.html:64
#, python-format
msgid "Page %(current)s of %(total)s"
+msgstr "Page %(current)s of %(total)s"
+
+#: templates/django_tables2/bootstrap.html:64
+msgid "next"
msgstr ""
-#: templates/django_tables2/table.html:63
+#: templates/django_tables2/table.html:56
+msgid "Previous"
+msgstr "Previous"
+
+#: templates/django_tables2/table.html:72
msgid "Next"
-msgstr ""
+msgstr "Next"
-#: templates/django_tables2/table.html:66
+#: templates/django_tables2/table.html:78
#, python-format
msgid "%(count)s of %(total)s"
-msgstr ""
+msgstr "%(count)s of %(total)s"
diff --git a/django_tables2/locale/it/LC_MESSAGES/django.mo b/django_tables2/locale/it/LC_MESSAGES/django.mo
new file mode 100644
index 0000000..55b4ba7
Binary files /dev/null and b/django_tables2/locale/it/LC_MESSAGES/django.mo differ
diff --git a/django_tables2/locale/it/LC_MESSAGES/django.po b/django_tables2/locale/it/LC_MESSAGES/django.po
new file mode 100644
index 0000000..7a2ee7a
--- /dev/null
+++ b/django_tables2/locale/it/LC_MESSAGES/django.po
@@ -0,0 +1,45 @@
+# This file is distributed under the same license as the django-tables2 package
+msgid ""
+msgstr ""
+"Project-Id-Version: django-tables2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-04-19 10:23+0200\n"
+"PO-Revision-Date: 2016-04-14 11:21+0200\n"
+"Last-Translator: Paolo Dina <paolo at php3.it>\n"
+"Language-Team: Italian <it at li.org>\n"
+"Language: it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: templates/django_tables2/bootstrap.html:35
+msgid "no results"
+msgstr "nessun risultato"
+
+#: templates/django_tables2/bootstrap.html:55
+msgid "previous"
+msgstr "indietro"
+
+#: templates/django_tables2/bootstrap.html:59
+#: templates/django_tables2/table.html:64
+#, python-format
+msgid "Page %(current)s of %(total)s"
+msgstr "Pagina %(current)s di %(total)s"
+
+#: templates/django_tables2/bootstrap.html:64
+msgid "next"
+msgstr "avanti"
+
+#: templates/django_tables2/table.html:56
+msgid "Previous"
+msgstr "Indietro"
+
+#: templates/django_tables2/table.html:72
+msgid "Next"
+msgstr "Avanti"
+
+#: templates/django_tables2/table.html:78
+#, python-format
+msgid "%(count)s of %(total)s"
+msgstr "%(count)s di %(total)s"
diff --git a/django_tables2/locale/nl/LC_MESSAGES/django.mo b/django_tables2/locale/nl/LC_MESSAGES/django.mo
new file mode 100644
index 0000000..0434b6b
Binary files /dev/null and b/django_tables2/locale/nl/LC_MESSAGES/django.mo differ
diff --git a/django_tables2/locale/nl/LC_MESSAGES/django.po b/django_tables2/locale/nl/LC_MESSAGES/django.po
new file mode 100644
index 0000000..959eb5e
--- /dev/null
+++ b/django_tables2/locale/nl/LC_MESSAGES/django.po
@@ -0,0 +1,45 @@
+# This file is distributed under the same license as the django-tables2 package
+msgid ""
+msgstr ""
+"Project-Id-Version: django-tables2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-04-19 10:23+0200\n"
+"PO-Revision-Date: 2016-04-19 10:21+0200\n"
+"Last-Translator: Jan Pieter Waagmeester <jieter at jieter.nl>\n"
+"Language-Team: Dutch <nl at li.org>\n"
+"Language: nl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: templates/django_tables2/bootstrap.html:35
+msgid "no results"
+msgstr "geen resultaten"
+
+#: templates/django_tables2/bootstrap.html:55
+msgid "previous"
+msgstr "vorige"
+
+#: templates/django_tables2/bootstrap.html:59
+#: templates/django_tables2/table.html:64
+#, python-format
+msgid "Page %(current)s of %(total)s"
+msgstr "Pagina %(current)s van %(total)s"
+
+#: templates/django_tables2/bootstrap.html:64
+msgid "next"
+msgstr "volgende"
+
+#: templates/django_tables2/table.html:56
+msgid "Previous"
+msgstr "Vorige"
+
+#: templates/django_tables2/table.html:72
+msgid "Next"
+msgstr "Volgende"
+
+#: templates/django_tables2/table.html:78
+#, python-format
+msgid "%(count)s of %(total)s"
+msgstr "%(count)s van %(total)s"
diff --git a/django_tables2/rows.py b/django_tables2/rows.py
index ebae191..add767b 100644
--- a/django_tables2/rows.py
+++ b/django_tables2/rows.py
@@ -1,9 +1,12 @@
# coding: utf-8
+
+
from django.db import models
from django.db.models.fields import FieldDoesNotExist
from django.utils import six
-from .utils import A, getargspec
+from .columns.linkcolumn import BaseLinkColumn
+from .utils import A, AttributeDict, computed_values, signature
class BoundRow(object):
@@ -32,31 +35,27 @@ class BoundRow(object):
1
<input type="checkbox" name="my_chkbox" value="2" />
- Alternatively you can treat it like a list and use indexing to retrieve a
- specific cell. It should be noted that this will raise an IndexError on
- failure.
+ Alternatively you can use row.get_cell() to retrieve a specific cell.
.. code-block:: python
- >>> row[0]
+ >>> row.get_cell(0)
1
- >>> row[1]
+ >>> row.get_cell(1)
u'<input type="checkbox" name="my_chkbox" value="2" />'
- >>> row[2]
+ >>> row.get_cell(2)
...
IndexError: list index out of range
- Finally you can also treat it like a dictionary and use column names as the
- keys. This will raise KeyError on failure (unlike the above indexing using
- integers).
+ Finally you can also use the column names to retrieve a specific cell:
.. code-block:: python
- >>> row['a']
+ >>> row.get_cell('a')
1
- >>> row['b']
+ >>> row.get_cell('b')
u'<input type="checkbox" name="my_chkbox" value="2" />'
- >>> row['c']
+ >>> row.get_cell('c')
...
KeyError: 'c'
@@ -76,6 +75,20 @@ class BoundRow(object):
return self._table
@property
+ def attrs(self):
+ '''Return the attributes for a certain row.'''
+ cssClass = 'even' if next(self._table._counter) % 2 == 0 else 'odd'
+
+ row_attrs = computed_values(self._table.row_attrs, self._record)
+
+ if 'class' in row_attrs:
+ row_attrs['class'] += ' ' + cssClass
+ else:
+ row_attrs['class'] = cssClass
+
+ return AttributeDict(row_attrs)
+
+ @property
def record(self):
"""
The data record from the data source which is used to populate this row
@@ -95,7 +108,7 @@ class BoundRow(object):
# is correct – it's what __getitem__ expects.
yield value
- def __getitem__(self, name):
+ def get_cell(self, name):
"""
Returns the final rendered value for a cell in the row, given the name
of a column.
@@ -103,30 +116,42 @@ class BoundRow(object):
bound_column = self.table.columns[name]
value = None
+ accessor = A(bound_column.accessor)
+
# We need to take special care here to allow get_FOO_display()
# methods on a model to be used if available. See issue #30.
- path, _, remainder = bound_column.accessor.rpartition('.')
- penultimate = A(path).resolve(self.record, quiet=True)
+ penultimate, remainder = accessor.penultimate(self.record)
+
# If the penultimate is a model and the remainder is a field
# using choices, use get_FOO_display().
if isinstance(penultimate, models.Model):
try:
- field = penultimate._meta.get_field(remainder)
- display = getattr(penultimate, 'get_%s_display' % remainder, None)
- if getattr(field, "choices", ()) and display:
- value = display()
+ field = accessor.get_field(self.record)
+ display_fn = getattr(penultimate, 'get_%s_display' % remainder, None)
+ if getattr(field, 'choices', ()) and display_fn:
+ value = display_fn()
remainder = None
except FieldDoesNotExist:
pass
- # Fall back to just using the original accessor (we just need
- # to follow the remainder).
+
+ # Fall back to just using the original accessor
if remainder:
- value = A(remainder).resolve(penultimate, quiet=True)
+ try:
+ value = accessor.resolve(self.record)
+ except Exception:
+ # we need to account for non-field based columns (issue #257)
+ is_linkcolumn = isinstance(bound_column.column, BaseLinkColumn)
+ if is_linkcolumn and bound_column.column.text is not None:
+ return self._call_render(bound_column)
if value in bound_column.column.empty_values:
return bound_column.default
- available = {
+ return self._call_render(bound_column, value)
+
+ def _call_render(self, bound_column, value=None):
+ '''Call the column's render method with appropriate kwargs'''
+ kwargs = {
'value': value,
'record': self.record,
'column': bound_column.column,
@@ -134,19 +159,15 @@ class BoundRow(object):
'bound_row': self,
'table': self._table,
}
- expected = {}
- # provide only the arguments expected by `render`
- argspec = getargspec(bound_column.render)
- args, varkw = argspec[0], argspec[2]
- if varkw:
- expected = available
- else:
- for key, value in available.items():
- if key in args[1:]:
- expected[key] = value
+ # inspect signature of the render()-method. If the **kwargs argument is
+ # defined, pass all arguments, else provide exactly the kwargs wanted.
+ args, keywords = signature(bound_column.render)
+
+ if keywords is None:
+ kwargs = {key: kwargs[key] for key in kwargs if key in args}
- return bound_column.render(**expected)
+ return bound_column.render(**kwargs)
def __contains__(self, item):
"""Check by both row object and column name."""
@@ -163,7 +184,7 @@ class BoundRow(object):
``rendered within ``<td>``.
"""
for column in self.table.columns:
- yield (column, self[column.name])
+ yield (column, self.get_cell(column.name))
class BoundRows(object):
diff --git a/django_tables2/tables.py b/django_tables2/tables.py
index 9fc5ebe..ebeca98 100644
--- a/django_tables2/tables.py
+++ b/django_tables2/tables.py
@@ -3,6 +3,7 @@ from __future__ import unicode_literals
import copy
from collections import OrderedDict
+from itertools import count
from django.core.paginator import Paginator
from django.db.models.fields import FieldDoesNotExist
@@ -154,7 +155,7 @@ class DeclarativeColumnsMetaclass(type):
``base_columns`` as well.
"""
def __new__(mcs, name, bases, attrs):
- attrs["_meta"] = opts = TableOptions(attrs.get("Meta", None))
+ attrs['_meta'] = opts = TableOptions(attrs.get('Meta', None))
# extract declared columns
cols, remainder = [], {}
for attr_name, attr in attrs.items():
@@ -171,10 +172,10 @@ class DeclarativeColumnsMetaclass(type):
# necessary to preserve the correct order of columns.
parent_columns = []
for base in bases[::-1]:
- if hasattr(base, "base_columns"):
+ if hasattr(base, 'base_columns'):
parent_columns = list(base.base_columns.items()) + parent_columns
# Start with the parent columns
- attrs["base_columns"] = OrderedDict(parent_columns)
+ attrs['base_columns'] = OrderedDict(parent_columns)
# Possibly add some generated columns based on a model
if opts.model:
extra = OrderedDict()
@@ -193,23 +194,23 @@ class DeclarativeColumnsMetaclass(type):
else:
for field in opts.model._meta.fields:
extra[field.name] = columns.library.column_for_field(field)
- attrs["base_columns"].update(extra)
+ attrs['base_columns'].update(extra)
# Explicit columns override both parent and generated columns
- attrs["base_columns"].update(OrderedDict(cols))
+ attrs['base_columns'].update(OrderedDict(cols))
# Apply any explicit exclude setting
for exclusion in opts.exclude:
- if exclusion in attrs["base_columns"]:
- attrs["base_columns"].pop(exclusion)
+ if exclusion in attrs['base_columns']:
+ attrs['base_columns'].pop(exclusion)
# Now reorder the columns based on explicit sequence
if opts.sequence:
- opts.sequence.expand(attrs["base_columns"].keys())
+ opts.sequence.expand(attrs['base_columns'].keys())
# Table's sequence defaults to sequence declared in Meta
# attrs['_sequence'] = opts.sequence
- attrs["base_columns"] = OrderedDict(((x, attrs["base_columns"][x]) for x in opts.sequence))
+ attrs['base_columns'] = OrderedDict(((x, attrs['base_columns'][x]) for x in opts.sequence))
# set localize on columns
- for col_name in attrs["base_columns"].keys():
+ for col_name in attrs['base_columns'].keys():
localize_column = None
if col_name in opts.localize:
localize_column = True
@@ -218,7 +219,7 @@ class DeclarativeColumnsMetaclass(type):
localize_column = False
if localize_column is not None:
- attrs["base_columns"][col_name].localize = localize_column
+ attrs['base_columns'][col_name].localize = localize_column
return super(DeclarativeColumnsMetaclass, mcs).__new__(mcs, name, bases, attrs)
@@ -234,27 +235,28 @@ class TableOptions(object):
"""
def __init__(self, options=None):
super(TableOptions, self).__init__()
- self.attrs = AttributeDict(getattr(options, "attrs", {}))
- self.default = getattr(options, "default", "—")
- self.empty_text = getattr(options, "empty_text", None)
- self.fields = getattr(options, "fields", None)
- self.exclude = getattr(options, "exclude", ())
- order_by = getattr(options, "order_by", None)
+ self.attrs = AttributeDict(getattr(options, 'attrs', {}))
+ self.row_attrs = getattr(options, 'row_attrs', {})
+ self.default = getattr(options, 'default', '—')
+ self.empty_text = getattr(options, 'empty_text', None)
+ self.fields = getattr(options, 'fields', None)
+ self.exclude = getattr(options, 'exclude', ())
+ order_by = getattr(options, 'order_by', None)
if isinstance(order_by, six.string_types):
order_by = (order_by, )
self.order_by = OrderByTuple(order_by) if order_by is not None else None
- self.order_by_field = getattr(options, "order_by_field", "sort")
- self.page_field = getattr(options, "page_field", "page")
- self.per_page = getattr(options, "per_page", 25)
- self.per_page_field = getattr(options, "per_page_field", "per_page")
- self.prefix = getattr(options, "prefix", "")
- self.show_header = getattr(options, "show_header", True)
- self.sequence = Sequence(getattr(options, "sequence", ()))
- self.orderable = getattr(options, "orderable", True)
- self.model = getattr(options, "model", None)
- self.template = getattr(options, "template", "django_tables2/table.html")
- self.localize = getattr(options, "localize", ())
- self.unlocalize = getattr(options, "unlocalize", ())
+ self.order_by_field = getattr(options, 'order_by_field', 'sort')
+ self.page_field = getattr(options, 'page_field', 'page')
+ self.per_page = getattr(options, 'per_page', 25)
+ self.per_page_field = getattr(options, 'per_page_field', 'per_page')
+ self.prefix = getattr(options, 'prefix', '')
+ self.show_header = getattr(options, 'show_header', True)
+ self.sequence = Sequence(getattr(options, 'sequence', ()))
+ self.orderable = getattr(options, 'orderable', True)
+ self.model = getattr(options, 'model', None)
+ self.template = getattr(options, 'template', 'django_tables2/table.html')
+ self.localize = getattr(options, 'localize', ())
+ self.unlocalize = getattr(options, 'unlocalize', ())
class TableBase(object):
@@ -390,9 +392,10 @@ class TableBase(object):
TableDataClass = TableData
def __init__(self, data, order_by=None, orderable=None, empty_text=None,
- exclude=None, attrs=None, sequence=None, prefix=None,
- order_by_field=None, page_field=None, per_page_field=None,
- template=None, default=None, request=None, show_header=None):
+ exclude=None, attrs=None, row_attrs=None, sequence=None,
+ prefix=None, order_by_field=None, page_field=None,
+ per_page_field=None, template=None, default=None, request=None,
+ show_header=None):
super(TableBase, self).__init__()
self.exclude = exclude or ()
self.sequence = sequence
@@ -403,6 +406,7 @@ class TableBase(object):
self.rows = BoundRows(data=self.data, table=self)
attrs = computed_values(attrs if attrs is not None else self._meta.attrs)
self.attrs = AttributeDict(attrs)
+ self.row_attrs = AttributeDict(row_attrs or self._meta.row_attrs)
self.empty_text = empty_text if empty_text is not None else self._meta.empty_text
self.orderable = orderable
self.prefix = prefix
@@ -451,10 +455,14 @@ class TableBase(object):
if request:
RequestConfig(request).configure(self)
+ self._counter = count()
+
def as_html(self, request):
"""
Render the table to a simple HTML table, adding `request` to the context.
"""
+ # reset counter for new rendering
+ self._counter = count()
template = get_template(self.template)
context = {
diff --git a/django_tables2/templates/django_tables2/bootstrap.html b/django_tables2/templates/django_tables2/bootstrap.html
index f15078c..68589a4 100644
--- a/django_tables2/templates/django_tables2/bootstrap.html
+++ b/django_tables2/templates/django_tables2/bootstrap.html
@@ -24,7 +24,7 @@
<tbody>
{% for row in table.page.object_list|default:table.rows %} {# support pagination #}
{% block table.tbody.row %}
- <tr class="{% cycle "odd" "even" %}">
+ <tr {{ row.attrs.as_html }}>
{% for column, cell in row.items %}
<td {{ column.attrs.td.as_html }}>{{ cell }}</td>
{% endfor %}
@@ -56,9 +56,7 @@
</a>
{% endif %}
<li class="cardinality">
- {% blocktrans with table.page.number as current and table.paginator.num_pages as total %}
- Page {{ current }} of {{ total }}
- {% endblocktrans %}
+ {% blocktrans with table.page.number as current and table.paginator.num_pages as total %}Page {{ current }} of {{ total }}{% endblocktrans %}
</li>
{% if table.page.has_next %}
<li class="next">
diff --git a/django_tables2/templates/django_tables2/table.html b/django_tables2/templates/django_tables2/table.html
index ee5a0f4..f011ae6 100644
--- a/django_tables2/templates/django_tables2/table.html
+++ b/django_tables2/templates/django_tables2/table.html
@@ -23,7 +23,7 @@
<tbody>
{% for row in table.page.object_list|default:table.rows %} {# support pagination #}
{% block table.tbody.row %}
- <tr class="{% cycle 'even' 'odd' %}">
+ <tr {{ row.attrs.as_html }}>
{% for column, cell in row.items %}
<td {{ column.attrs.td.as_html }}>{% if column.localize == None %}{{ cell }}{% else %}{% if column.localize %}{{ cell|localize }}{% else %}{{ cell|unlocalize }}{% endif %}{% endif %}</td>
{% endfor %}
@@ -61,9 +61,7 @@
{% if table.page.has_previous or table.page.has_next %}
{% block pagination.current %}
<li class="current">
- {% blocktrans with table.page.number as current and table.paginator.num_pages as total %}
- Page {{ current }} of {{ total }}
- {% endblocktrans %}
+ {% blocktrans with table.page.number as current and table.paginator.num_pages as total %}Page {{ current }} of {{ total }}{% endblocktrans %}
</li>
{% endblock pagination.current %}
{% endif %}
diff --git a/django_tables2/utils.py b/django_tables2/utils.py
index 654293c..f503163 100644
--- a/django_tables2/utils.py
+++ b/django_tables2/utils.py
@@ -1,7 +1,6 @@
# coding: utf-8
from __future__ import absolute_import, unicode_literals
-import inspect
from functools import total_ordering
from itertools import chain
@@ -109,7 +108,8 @@ class OrderBy(six.text_type):
@six.python_2_unicode_compatible
class OrderByTuple(tuple):
- """Stores ordering as (as `.OrderBy` objects). The
+ """
+ Stores ordering as (as `.OrderBy` objects). The
... 2764 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/django-tables.git
More information about the Python-modules-commits
mailing list