[Python-modules-commits] [django-tables] 01/07: Import django-tables_1.0.4.orig.tar.gz
Brian May
bam at moszumanska.debian.org
Thu Oct 22 03:33:56 UTC 2015
This is an automated email from the git hooks/post-receive script.
bam pushed a commit to branch master
in repository django-tables.
commit 7cb0fb4b7257da41155bae663e56db991f3222ca
Author: Brian May <bam at debian.org>
Date: Thu Oct 22 10:35:34 2015 +1100
Import django-tables_1.0.4.orig.tar.gz
---
.travis.yml | 18 +-
README.rst => README.md | 132 ++-
django_tables2/__init__.py | 4 +-
django_tables2/columns/base.py | 73 +-
django_tables2/locale/de/LC_MESSAGES/django.mo | Bin 0 -> 646 bytes
django_tables2/locale/de/LC_MESSAGES/django.po | 37 +
django_tables2/locale/sv/LC_MESSAGES/django.mo | Bin 0 -> 606 bytes
django_tables2/locale/sv/LC_MESSAGES/django.po | 32 +
django_tables2/rows.py | 2 +-
django_tables2/tables.py | 24 +-
django_tables2/templatetags/django_tables2.py | 4 +-
django_tables2/utils.py | 2 +-
docs/index.rst | 1268 +-----------------------
docs/pages/accessors.rst | 30 +
docs/pages/api-reference.rst | 322 ++++++
docs/pages/builtin-columns.rst | 18 +
docs/pages/column-attributes.rst | 28 +
docs/pages/column-headers.rst | 39 +
docs/pages/custom-rendering.rst | 142 +++
docs/pages/generic-mixins.rst | 63 ++
docs/pages/glossary.rst | 57 ++
docs/{ => pages}/internal.rst | 0
docs/pages/localization-control.rst | 50 +
docs/pages/order-by-accessors.rst | 48 +
docs/pages/pagination.rst | 24 +
docs/pages/query-string-fields.rst | 34 +
docs/pages/swapping-columns.rst | 21 +
docs/pages/table-data.rst | 48 +
docs/pages/table-mixins.rst | 31 +
docs/pages/tables-for-models.rst | 33 +
docs/pages/template-filters.rst | 19 +
docs/pages/template-tags.rst | 66 ++
docs/pages/tutorial.rst | 97 ++
docs/pages/upgrading-from-v1.rst | 62 ++
requirements/common.pip | 8 +
requirements/django-1.3.x.pip | 2 +
requirements/django-1.4.x.pip | 2 +
requirements/django-1.5.x.pip | 2 +
requirements/django-1.6.x.pip | 2 +
requirements/django-1.7.x.pip | 2 +
requirements/django-1.8.x.pip | 2 +
requirements/django-dev.pip | 2 +
setup.py | 8 +-
tests/__init__.py | 49 -
tests/app/models.py | 8 +-
tests/columns.py | 839 ----------------
tests/columns/__init__.py | 0
tests/columns/test_booleancolumn.py | 56 ++
tests/columns/test_checkboxcolumn.py | 31 +
tests/columns/test_datecolumn.py | 66 ++
tests/columns/test_datetimecolumn.py | 81 ++
tests/columns/test_emailcolumn.py | 39 +
tests/columns/test_filecolumn.py | 81 ++
tests/columns/test_general.py | 329 ++++++
tests/columns/test_linkcolumn.py | 95 ++
tests/columns/test_templatecolumn.py | 36 +
tests/columns/test_urlcolumn.py | 26 +
tests/{config.py => test_config.py} | 25 +-
tests/{core.py => test_core.py} | 154 ++-
tests/{models.py => test_models.py} | 58 +-
tests/{rows.py => test_rows.py} | 22 +-
tests/{templates.py => test_templates.py} | 207 ++--
tests/{utils.py => test_utils.py} | 56 +-
tests/{views.py => test_views.py} | 14 +-
tests/utils.py | 204 +---
tox.ini | 210 +---
66 files changed, 2685 insertions(+), 2859 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 0b92d61..2d1ce8b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,21 +2,21 @@ language: python
python:
- 2.7
env:
+ - TOX_ENV=py34-dj18
+ - TOX_ENV=py34-dj17
+ - TOX_ENV=py34-dj16
+ - TOX_ENV=py34-dj15
+ - TOX_ENV=py33-dj18
+ - TOX_ENV=py33-dj17
- TOX_ENV=py33-dj16
- TOX_ENV=py33-dj15
- - TOX_ENV=py32-dj16
- - TOX_ENV=py32-dj15
+ - TOX_ENV=py27-dj18
+ - TOX_ENV=py27-dj17
- TOX_ENV=py27-dj16
- TOX_ENV=py27-dj15
- TOX_ENV=py27-dj14
- TOX_ENV=py27-dj13
- - TOX_ENV=py27-dj12
- - TOX_ENV=py26-dj16
- - TOX_ENV=py26-dj15
- - TOX_ENV=py26-dj14
- - TOX_ENV=py26-dj13
- - TOX_ENV=py26-dj12
install:
- pip install tox
script:
- - tox -e $TOX_ENV
\ No newline at end of file
+ - tox -e $TOX_ENV
diff --git a/README.rst b/README.md
similarity index 70%
rename from README.rst
rename to README.md
index 868c7da..27277fb 100644
--- a/README.rst
+++ b/README.md
@@ -1,16 +1,13 @@
-================================================
django-tables2 - An app for creating HTML tables
================================================
-.. figure:: https://travis-ci.org/bradleyayers/django-tables2.png
+[](https://travis-ci.org/bradleyayers/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. e.g.
+`django.forms` does for HTML forms. e.g.
-.. figure:: http://dl.dropbox.com/u/33499139/django-tables2/example.png
- :align: center
- :alt: An example table rendered using django-tables2
+
Its features include:
@@ -22,12 +19,10 @@ Its features include:
- Pagination.
- Column based table sorting.
- Template tag to enable trivial rendering to HTML.
-- Generic view mixin for use in Django 1.3.
+- Generic view mixin.
Creating a table is as simple as:
-.. code-block:: python
-
import django_tables2 as tables
class SimpleTable(tables.Table):
@@ -36,48 +31,91 @@ Creating a table is as simple as:
This would then be used in a view:
-.. code-block:: python
-
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::
+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.
-
-.. __: http://django-tables2.readthedocs.org/en/latest/
+more! Check out the [documentation](http://django-tables2.readthedocs.org/en/latest/) for more details.
Building the documentation
==========================
If you want to build the docs from within a virtualenv, and Sphinx is installed
-globally, use::
+globally, use:
make html SPHINXBUILD="python $(which sphinx-build)"
+Publishing a release
+====================
+
+1. Bump the version in `django-tables2/__init__.py`.
+2. Update `README.rst`.
+3. Run `python setup.py sdist upload --sign --identity=<your gpg identity>`.
+
Change log
==========
+v1.0.4
+------
+
+- Fix bug in retrieving `field.verbose_name` under Django 1.8.
+
+v1.0.3
+------
+
+- Remove setup.cfg as PyPI doesn't actually support it, instead it's a distutils2 thing that's been discontinued.
+
+v1.0.2
+------
+
+- Add setup.cfg to declare README.md for PyPI.
+
+v1.0.1
+------
+
+- Convert README to markdown so it's formatted nicely on PyPI.
+
+v1.0.0
+------
+
+- Travis CI builds pass.
+- Added Python 3.4 support.
+- Added Django 1.7 and Django 1.8 support.
+- Dropped Python 2.6 and 3.2 support.
+- Drop Django 1.2 support
+- Convert tests to using py.test.
+
+v0.16.0
+-------
+
+- Django 1.8 fixes
+- `BoundColumn.verbose_name` now titlises only if no verbose_name was given.
+ `verbose_name` is used verbatim.
+- Add max_length attribute to person CharField
+- Add Swedish translation
+- Update docs presentation on readthedocs
+
+
v0.15.0
-------
- Add UK, Russian, Spanish, Portuguese, and Polish translations
-- Add support for computed table ``attrs``.
+- Add support for computed table `attrs`.
v0.14.0
-------
-- ``querystring`` and ``seturlparam`` template tags now require the request to
+- `querystring` and `seturlparam` template tags now require the request to
be in the context (backwards incompatible) -- #127
- Add Travis CI support
- Add support for Django 1.5
@@ -95,7 +133,7 @@ v0.13.0
v0.12.1
-------
-- When resolving an accessor, *all* exceptions are smothered into ``None``.
+- When resolving an accessor, *all* exceptions are smothered into `None`.
v0.12.0
-------
@@ -103,35 +141,35 @@ v0.12.0
- Improve performance by removing unnecessary queries
- Simplified pagination:
- - ``Table.page`` is an instance attribute (no longer ``@property``)
- - Exceptions raised by paginators (e.g. ``EmptyPage``) are no longer
- smothered by ``Table.page``
- - Pagination exceptions are raised by ``Table.paginate``
- - ``RequestConfig`` can handles pagination errors silently, can be disabled
- by including ``silent=False`` in the ``paginate`` argument value
+ - `Table.page` is an instance attribute (no longer `@property`)
+ - Exceptions raised by paginators (e.g. `EmptyPage`) are no longer
+ smothered by `Table.page`
+ - Pagination exceptions are raised by `Table.paginate`
+ - `RequestConfig` can handles pagination errors silently, can be disabled
+ by including `silent=False` in the `paginate` argument value
-- Add ``DateTimeColumn`` and ``DateColumn`` to handle formatting ``datetime``
+- Add `DateTimeColumn` and `DateColumn` to handle formatting `datetime`
and timezones.
-- Add ``BooleanColumn`` to handle bool values
-- ``render_table`` can now build and render a table for a queryset, rather than
+- Add `BooleanColumn` to handle bool values
+- `render_table` can now build and render a table for a queryset, rather than
needing to be passed a table instance
- Table columns created automatically from a model now use specialised columns
-- ``Column.render`` is now skipped if the value is considered *empty*, the
+- `Column.render` is now skipped if the value is considered *empty*, the
default value is used instead. Empty values are specified via
- ``Column.empty_values``, by default is ``(None, '')`` (backward incompatible)
-- Default values can now be specified on table instances or ``Table.Meta``
-- Accessor's now honor ``alters_data`` during resolving. Fixes issue that would
- delete all your data when a column had an accessor of ``delete``
-- Add ``default`` and ``value`` to context of ``TemplateColumn``
+ `Column.empty_values`, by default is `(None, '')` (backward incompatible)
+- Default values can now be specified on table instances or `Table.Meta`
+- Accessor's now honor `alters_data` during resolving. Fixes issue that would
+ delete all your data when a column had an accessor of `delete`
+- Add `default` and `value` to context of `TemplateColumn`
- Add cardinality indication to the pagination area of a table
-- ``Attrs`` is deprecated, use ``dict`` instead
+- `Attrs` is deprecated, use `dict` instead
v0.11.0
-------
-- Add ``URLColumn`` to render URLs in a data source into hyperlinks
-- Add ``EmailColumn`` to render email addresses into hyperlinks
-- ``TemplateColumn`` can now Django's template loaders to render from a file
+- Add `URLColumn` to render URLs in a data source into hyperlinks
+- Add `EmailColumn` to render email addresses into hyperlinks
+- `TemplateColumn` can now Django's template loaders to render from a file
v0.10.4
-------
@@ -164,7 +202,7 @@ v0.10.1
v0.10.0
-------
-- Renamed `BoundColumn.order_by` to `order_by_alias` and never returns ``None``
+- Renamed `BoundColumn.order_by` to `order_by_alias` and never returns `None`
(**Backwards incompatible**). Templates are affected if they use something
like:
@@ -210,14 +248,14 @@ v0.9.4
v0.9.3
------
-- Fix regression in ``SingleTableMixin``.
+- Fix regression in `SingleTableMixin`.
- Remove stray `print` statement.
v0.9.2
------
- `SingleTableView` now uses `RequestConfig`. This fixes issues with
- ``order_by_field`, `page_field`, and `per_page_field` not being honored.
+ `order_by_field`, `page_field`, and `per_page_field` not being honored.
- Add `Table.Meta.per_page` and change `Table.paginate` to use it as default.
- Add `title` template filter. It differs from Django's built-in `title` filter
because it operates on an individual word basis and leaves words containing
@@ -293,9 +331,9 @@ v0.8.0
v0.7.8
------
-- Tables now support using both ``sequence`` and ``exclude`` (issue #32).
-- ``Sequence`` class moved to ``django_tables2/utils.py``.
-- Table instances now support modification to the ``exclude`` property.
-- Removed ``BoundColumns._spawn_columns``.
-- ``Table.data``, ``Table.rows``, and ``Table.columns`` are now attributes
+- Tables now support using both `sequence` and `exclude` (issue #32).
+- `Sequence` class moved to `django_tables2/utils.py`.
+- Table instances now support modification to the `exclude` property.
+- Removed `BoundColumns._spawn_columns`.
+- `Table.data`, `Table.rows`, and `Table.columns` are now attributes
rather than properties.
diff --git a/django_tables2/__init__.py b/django_tables2/__init__.py
index 138d1ae..9b33576 100644
--- a/django_tables2/__init__.py
+++ b/django_tables2/__init__.py
@@ -7,9 +7,9 @@ from .columns import (BooleanColumn, Column, CheckBoxColumn, DateColumn,
from .config import RequestConfig
from .utils import A, Attrs
try:
- from .views import SingleTableMixin, SingleTableView
+ from .views import SingleTableMixin, SingleTableView
except ImportError:
pass
-__version__ = "0.15.0"
+__version__ = "1.0.4"
diff --git a/django_tables2/columns/base.py b/django_tables2/columns/base.py
index df95d33..ea27678 100644
--- a/django_tables2/columns/base.py
+++ b/django_tables2/columns/base.py
@@ -1,13 +1,16 @@
# coding: utf-8
from __future__ import absolute_import, unicode_literals
+from collections import OrderedDict
+from itertools import islice
+import warnings
+
from django.db.models.fields import FieldDoesNotExist
-from django.utils.datastructures import SortedDict
-from django.utils.safestring import SafeData
+from django import VERSION as django_version
+import six
+
from django_tables2.templatetags.django_tables2 import title
from django_tables2.utils import A, AttributeDict, OrderBy, OrderByTuple
-from itertools import islice
-import six
-import warnings
+from ..utils import python_2_unicode_compatible
class Library(object):
@@ -116,9 +119,6 @@ class Column(object): # pylint: disable=R0902
:type: `unicode`
- This should not defined in title case, but rather natural case. It is
- converted to title case for use in column headers.
-
.. attribute:: visible
@@ -129,8 +129,6 @@ class Column(object): # pylint: disable=R0902
.. attribute:: localize
- This attribute doesn't work in Django 1.2
-
* If `True`, cells of this column will be localized in the HTML output
by the localize filter.
@@ -188,9 +186,7 @@ class Column(object): # pylint: disable=R0902
"""
The value used for the column heading (e.g. inside the ``<th>`` tag).
- By default this titlises the `~.Column.verbose_name`. If
- `~.Column.verbose_name` is an instance of `~.safestring.SafeData`, it's
- used unmodified.
+ By default this returns `~.Column.verbose_name`.
:returns: `unicode` or `None`
@@ -203,12 +199,7 @@ class Column(object): # pylint: disable=R0902
accessing that first) when this property doesn't return something
useful.
"""
- if self.verbose_name:
- if isinstance(self.verbose_name, SafeData):
- # If the author has used mark_safe, we're going to assume the
- # author wants the value used verbatim.
- return self.verbose_name
- return title(self.verbose_name)
+ return self.verbose_name
def render(self, value):
"""
@@ -253,9 +244,14 @@ class Column(object): # pylint: disable=R0902
# Since this method is inherited by every subclass, only provide a
# column if this class was asked directly.
if cls is Column:
- return cls(verbose_name=field.verbose_name)
+ if hasattr(field, "get_related_field"):
+ verbose_name = field.get_related_field().verbose_name
+ else:
+ verbose_name = field.verbose_name
+ return cls(verbose_name=verbose_name)
+ at python_2_unicode_compatible
class BoundColumn(object):
"""
A *run-time* version of `.Column`. The difference between
@@ -285,7 +281,7 @@ class BoundColumn(object):
self.column = column
self.name = name
- def __unicode__(self):
+ def __str__(self):
return six.text_type(self.header)
@property
@@ -350,13 +346,7 @@ class BoundColumn(object):
if column_header:
return column_header
# fall back to automatic best guess
- verbose_name = self.verbose_name # avoid calculating multiple times
- if isinstance(verbose_name, SafeData):
- # If the verbose_name has come from a model field, it's possible
- # that the author used mark_safe to include HTML in the value. If
- # this is the case, we leave it verbatim.
- return verbose_name
- return title(verbose_name)
+ return self.verbose_name
@property
def order_by(self):
@@ -453,7 +443,7 @@ class BoundColumn(object):
@property
def verbose_name(self):
"""
- Return the verbose name for this column, or fallback to prettified
+ Return the verbose name for this column, or fallback to the titlised
column name.
If the table is using queryset data, then use the corresponding model
@@ -461,9 +451,6 @@ class BoundColumn(object):
then get the last field in the accessor (i.e. stop when the
relationship turns from ORM relationships to object attributes [e.g.
person.upper should stop at person]).
-
- If the model field's `~.db.Field.verbose_name` is a
- `~.safestring.SafeData`, it's used unmodified.
"""
# Favor an explicit defined verbose_name
if self.column.verbose_name:
@@ -471,16 +458,21 @@ class BoundColumn(object):
# This is our reasonable fallback, should the next section not result
# in anything useful.
- name = self.name.replace('_', ' ')
+ name = title(self.name.replace('_', ' '))
- # Try to use a tmodel field's verbose_name
- if hasattr(self.table.data, 'queryset'):
+ # Try to use a model field's verbose_name
+ if hasattr(self.table.data, 'queryset') and hasattr(self.table.data.queryset, 'model'):
model = self.table.data.queryset.model
parts = self.accessor.split('.')
field = None
for part in parts:
+
try:
- field = model._meta.get_field(part)
+ if django_version < (1, 8, 0):
+ field, _, _, _ = model._meta.get_field_by_name(part)
+ else:
+ field = model._meta.get_field(part)
+
except FieldDoesNotExist:
break
if hasattr(field, 'rel') and hasattr(field.rel, 'to'):
@@ -488,7 +480,10 @@ class BoundColumn(object):
continue
break
if field:
- name = field.verbose_name
+ if hasattr(field, 'field'):
+ name = field.field.verbose_name
+ else:
+ name = field.verbose_name
return name
@property
@@ -518,7 +513,7 @@ class BoundColumns(object):
A `BoundColumns` object is a container for holding `BoundColumn` objects.
It provides methods that make accessing columns easier than if they were
stored in a `list` or `dict`. `Columns` has a similar API to a `dict` (it
- actually uses a `~django.utils.datastructures.SortedDict` interally).
+ actually uses a `~collections.OrderedDict` interally).
At the moment you'll only come across this class when you access a
`.Table.columns` property.
@@ -528,7 +523,7 @@ class BoundColumns(object):
"""
def __init__(self, table):
self.table = table
- self.columns = SortedDict()
+ self.columns = OrderedDict()
for name, column in six.iteritems(table.base_columns):
self.columns[name] = bc = BoundColumn(table, column, name)
bc.render = getattr(table, 'render_' + name, column.render)
diff --git a/django_tables2/locale/de/LC_MESSAGES/django.mo b/django_tables2/locale/de/LC_MESSAGES/django.mo
new file mode 100644
index 0000000..fbc014c
Binary files /dev/null and b/django_tables2/locale/de/LC_MESSAGES/django.mo differ
diff --git a/django_tables2/locale/de/LC_MESSAGES/django.po b/django_tables2/locale/de/LC_MESSAGES/django.po
new file mode 100644
index 0000000..569e050
--- /dev/null
+++ b/django_tables2/locale/de/LC_MESSAGES/django.po
@@ -0,0 +1,37 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-04-09 12:44+0200\n"
+"PO-Revision-Date: 2015-04-09 12:45+0100\n"
+"Language: de\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"
+"Last-Translator: Tim Schneider <tim.schneider at nb-dev.de>\n"
+"Language-Team: \n"
+"X-Generator: Poedit 1.7.5\n"
+
+#: templates/django_tables2/table.html:55
+msgid "Previous"
+msgstr "Zurück"
+
+#: templates/django_tables2/table.html:59
+#, python-format
+msgid "Page %(current)s of %(total)s"
+msgstr "Seite %(current)s von %(total)s"
+
+#: templates/django_tables2/table.html:63
+msgid "Next"
+msgstr "Weiter"
+
+#: templates/django_tables2/table.html:66
+#, python-format
+msgid "%(count)s of %(total)s"
+msgstr "%(count)s von %(total)s"
diff --git a/django_tables2/locale/sv/LC_MESSAGES/django.mo b/django_tables2/locale/sv/LC_MESSAGES/django.mo
new file mode 100644
index 0000000..53f6bfd
Binary files /dev/null and b/django_tables2/locale/sv/LC_MESSAGES/django.mo differ
diff --git a/django_tables2/locale/sv/LC_MESSAGES/django.po b/django_tables2/locale/sv/LC_MESSAGES/django.po
new file mode 100644
index 0000000..84955fb
--- /dev/null
+++ b/django_tables2/locale/sv/LC_MESSAGES/django.po
@@ -0,0 +1,32 @@
+# 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: 2012-09-18 03:12+0200\n"
+"PO-Revision-Date: 2014-12-04 10:25+0100\n"
+"Last-Translator: Petter Jönsson <pjr+git at petr.se>\n"
+"Language-Team: Swedish <sv at li.org>\n"
+"Language: sv\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: templates/django_tables2/table.html:55
+msgid "Previous"
+msgstr "Föregående"
+
+#: templates/django_tables2/table.html:59
+#, python-format
+msgid "Page %(current)s of %(total)s"
+msgstr "Sida %(current)s av %(total)s"
+
+#: templates/django_tables2/table.html:63
+msgid "Next"
+msgstr "Nästa"
+
+#: templates/django_tables2/table.html:66
+#, python-format
+msgid "%(count)s of %(total)s"
+msgstr "%(count)s av %(total)s"
diff --git a/django_tables2/rows.py b/django_tables2/rows.py
index d1125e2..bd2dd0f 100644
--- a/django_tables2/rows.py
+++ b/django_tables2/rows.py
@@ -112,7 +112,7 @@ class BoundRow(object):
try:
field = penultimate._meta.get_field(remainder)
display = getattr(penultimate, 'get_%s_display' % remainder, None)
- if field.choices and display:
+ if getattr(field, "choices", ()) and display:
value = display()
remainder = None
except FieldDoesNotExist:
diff --git a/django_tables2/tables.py b/django_tables2/tables.py
index 2758ad4..2f31069 100644
--- a/django_tables2/tables.py
+++ b/django_tables2/tables.py
@@ -6,11 +6,12 @@ from .rows import BoundRows
from .utils import (Accessor, AttributeDict, build_request, cached_property,
computed_values, OrderBy, OrderByTuple, segment, Sequence)
import copy
+import sys
from django.core.paginator import Paginator
from django.db.models.fields import FieldDoesNotExist
-from django.utils.datastructures import SortedDict
from django.template import RequestContext
from django.template.loader import get_template
+from collections import OrderedDict
import six
import warnings
@@ -34,12 +35,15 @@ class TableData(object):
self.queryset = data
# otherwise it must be convertable to a list
else:
- try:
+ # do some light validation
+ if hasattr(data, '__iter__') or (hasattr(data, '__len__') and hasattr(data, '__getitem__')):
self.list = list(data)
- except:
- raise ValueError('data must be QuerySet-like (have count and '
- 'order_by) or support list(data) -- %s has '
- 'neither' % type(data).__name__)
+ else:
+ raise ValueError(
+ 'data must be QuerySet-like (have count and '
+ 'order_by) or support list(data) -- %s has '
+ 'neither' % type(data).__name__
+ )
def __len__(self):
if not hasattr(self, "_length"):
@@ -168,10 +172,10 @@ class DeclarativeColumnsMetaclass(type):
if hasattr(base, "base_columns"):
parent_columns = list(base.base_columns.items()) + parent_columns
# Start with the parent columns
- attrs["base_columns"] = SortedDict(parent_columns)
+ attrs["base_columns"] = OrderedDict(parent_columns)
# Possibly add some generated columns based on a model
if opts.model:
- extra = SortedDict()
+ extra = OrderedDict()
# honor Table.Meta.fields, fallback to model._meta.fields
if opts.fields:
# Each item in opts.fields is the name of a model field or a
@@ -190,7 +194,7 @@ class DeclarativeColumnsMetaclass(type):
attrs["base_columns"].update(extra)
# Explicit columns override both parent and generated columns
- attrs["base_columns"].update(SortedDict(cols))
+ attrs["base_columns"].update(OrderedDict(cols))
# Apply any explicit exclude setting
for exclusion in opts.exclude:
if exclusion in attrs["base_columns"]:
@@ -200,7 +204,7 @@ class DeclarativeColumnsMetaclass(type):
opts.sequence.expand(attrs["base_columns"].keys())
# Table's sequence defaults to sequence declared in Meta
#attrs['_sequence'] = opts.sequence
- attrs["base_columns"] = SortedDict(((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():
diff --git a/django_tables2/templatetags/django_tables2.py b/django_tables2/templatetags/django_tables2.py
index 1e72d74..1ca91de 100644
--- a/django_tables2/templatetags/django_tables2.py
+++ b/django_tables2/templatetags/django_tables2.py
@@ -5,12 +5,12 @@ from django.core.exceptions import ImproperlyConfigured
from django.template import TemplateSyntaxError, Variable, Node
from django.template.loader import get_template, select_template
from django.template.defaultfilters import stringfilter, title as old_title
-from django.utils.datastructures import SortedDict
from django.utils.http import urlencode
from django.utils.html import escape
from django.utils.safestring import mark_safe
import django_tables2 as tables
from django_tables2.config import RequestConfig
+from collections import OrderedDict
import re
import six
import tokenize
@@ -35,7 +35,7 @@ def token_kwargs(bits, parser):
"""
if not bits:
return {}
- kwargs = SortedDict()
+ kwargs = OrderedDict()
while bits:
match = kwarg_re.match(bits[0])
if not match or not match.group(1):
diff --git a/django_tables2/utils.py b/django_tables2/utils.py
index 3d1c2c9..078c7fd 100644
--- a/django_tables2/utils.py
+++ b/django_tables2/utils.py
@@ -151,7 +151,7 @@ class OrderByTuple(tuple):
transformed.append(item)
return super(OrderByTuple, cls).__new__(cls, transformed)
- def __unicode__(self):
+ def __str__(self):
return ','.join(self)
def __contains__(self, name):
diff --git a/docs/index.rst b/docs/index.rst
index af6d3b4..eb7f77e 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -19,1266 +19,40 @@ Report bugs at http://github.com/bradleyayers/django-tables2/issues
.. toctree::
:hidden:
- internal
+ pages/tutorial
+ pages/table-data
+ pages/accessors
+ pages/order-by-accessors
+ pages/swapping-columns
+ pages/column-headers
+ pages/pagination
+ pages/custom-rendering
+ pages/query-string-fields
+ pages/column-attributes
+ pages/builtin-columns
+ pages/template-tags
+ pages/template-filters
+ pages/generic-mixins
+ pages/table-mixins
+ pages/tables-for-models
+ pages/localization-control
+ pages/api-reference
+ pages/upgrading-from-v1
+ pages/glossary
+ pages/internal
-Tutorial
-========
-1. ``pip install django-tables2``
-2. Add ``'django_tables2'`` to ``INSTALLED_APPS``
-3. Add ``'django.core.context_processors.request'`` to ``TEMPLATE_CONTEXT_PROCESSORS``
-We're going to run through creating a tutorial app. Let's start with a simple model::
- # tutorial/models.py
- class Person(models.Model):
- name = models.CharField(verbose_name="full name")
-Add some data so you have something to display in the table. Now write a view
-to pass a ``Person`` queryset into a template::
- # tutorial/views.py
- from django.shortcuts import render
- def people(request):
- return render(request, "people.html", {"people": Person.objects.all()})
-Finally, implement the template:
-.. sourcecode:: django
- {# tutorial/templates/people.html #}
- {% load render_table from django_tables2 %}
- <!doctype html>
- <html>
- <head>
- <link rel="stylesheet" href="{{ STATIC_URL }}django_tables2/themes/paleblue/css/screen.css" />
- </head>
- <body>
- {% render_table people %}
- </body>
- </html>
-Hook the view up in your URLs, and load the page, you should see:
-.. figure:: _static/tutorial.png
- :align: center
- :alt: An example table rendered using django-tables2
-While simple, passing a queryset directly to ``{% render_table %}`` doesn't
-allow for any customisation. For that, you must define a `.Table` class.
-::
- # tutorial/tables.py
- import django_tables2 as tables
- from tutorial.models import Person
-
- class PersonTable(tables.Table):
- class Meta:
- model = Person
- # add class="paleblue" to <table> tag
- attrs = {"class": "paleblue"}
-
-
-You'll then need to instantiate and configure the table in the view, before
-adding it to the context.
-
-::
-
- # tutorial/views.py
- from django.shortcuts import render
- from django_tables2 import RequestConfig
- from tutorial.models import Person
- from tutorial.tables import PersonTable
-
- def people(request):
- table = PersonTable(Person.objects.all())
- RequestConfig(request).configure(table)
- return render(request, 'people.html', {'table': table})
-
-Using `.RequestConfig` automatically pulls values from ``request.GET`` and
-updates the table accordingly. This enables data ordering and pagination.
-
-Rather than passing a queryset to ``{% render_table %}``, instead pass the
-table.
-
-.. sourcecode:: django
-
- {% render_table table %}
-
-.. note::
-
- ``{% render_table %}`` works best when it's used in a template that
- contains the current request in the context as ``request``. The easiest way
- to enable this, is to ensure that the ``TEMPLATE_CONTEXT_PROCESSORS``
- setting contains ``"django.core.context_processors.request"``.
-
-At this point you haven't actually customised anything, you've merely added the
-boilerplate code that ``{% render_table %}`` does for you when given a
-queryset. The remaining sections in this document describe how to change
-various aspects of the table.
-
-
-.. _table-data:
-
-Populating a table with data
-============================
-
-Tables are compatible with a range of input data structures. If you've seen the
-tutorial you'll have seen a queryset being used, however any iterable that
-supports :func:`len` and contains items that expose key-based accessed to
-column values is fine.
-
-An an example we'll demonstrate using list of dicts. When defining a table it's
-necessary to declare each column. If your data matches the fields in a model,
-columns can be declared automatically for you via the `Table.Meta.model`
-option, but for non-queryset data you'll probably want to declare
-them manually::
-
- import django_tables2 as tables
-
- data = [
- {"name": "Bradley"},
- {"name": "Stevie"},
- ]
-
- class NameTable(tables.Table):
- name = tables.Column()
-
- table = NameTable(data)
-
-You can use this technique to override columns that were automatically created
-via `Table.Meta.model` too::
-
- # models.py
- from django.db import models
-
- class Person(models.Model):
- name = models.CharField(max_length=200)
-
-
- # tables.py
- import django_tables2 as tables
- from .models import Person
-
- class PersonTable(tables.Table):
- name = tables.Column(verbose_name="full name")
-
- class Meta:
- model = Person
-
-
-.. _accessors:
-
-Specifying alternative data for a column
-========================================
-
-Each column has a "key" that describes which value to pull from each record to
-populate the column's cells. By default, this key is just the name given to the
-column, but it can be changed to allow foreign key traversal or other complex
-cases.
-
-To reduce ambiguity, rather than calling it a "key", it's been given the
-special name "accessor".
-
-Accessors are just dotted paths that describe how an object should be traversed
-to reach a specific value. To demonstrate how they work we'll use them
-directly::
-
- >>> from django_tables2 import A
- >>> data = {"abc": {"one": {"two": "three"}}}
- >>> A("abc.one.two").resolve(data)
- "three"
-
-Dots represent a relationships, and are attempted in this order:
-
-1. Dictionary lookup ``a[b]``
-2. Attribute lookup ``a.b``
-3. List index lookup ``a[int(b)]``
-
-Then, if the value is callable, it is called and the result is used.
-
-
-.. _order-by-accessors:
-
-Specifying alternative ordering for a column
-============================================
-
-When using queryset data, it's possible for a column to present a computed
-value that doesn't correspond to a column in the database. In this situation
-attempting to order the column will cause a database exception.
-
-Example::
-
- # models.py
- class Person(models.Model):
- first_name = models.CharField(max_length=200)
- family_name = models.CharField(max_length=200)
-
- @property
- def name(self):
... 6067 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