From 393b03b0eb62e9666f65d8cb28c6860e7e8e438a Mon Sep 17 00:00:00 2001 From: Bradley Ayers Date: Sun, 10 Jul 2011 08:21:49 +1000 Subject: [PATCH] updated some docstrings, fixed issue #16, added some tests for i18n support --- django_tables2/columns.py | 22 +++++++++++++--------- django_tables2/tables.py | 6 +++++- tests/columns.py | 18 ++++++++++++++++++ tests/models.py | 16 ++++++++++++++++ tests/testapp/models.py | 4 ++++ 5 files changed, 56 insertions(+), 10 deletions(-) diff --git a/django_tables2/columns.py b/django_tables2/columns.py index e711d71..d597f4a 100644 --- a/django_tables2/columns.py +++ b/django_tables2/columns.py @@ -17,8 +17,10 @@ class Column(object): :class:`Column` objects control the way a column (including the cells that fall within it) are rendered. - :param verbose_name: A pretty human readable version of the column name. - Typically this is used in the header cells in the HTML output. + :param verbose_name: A human readable version of the column name. + Typically this is used in the header cells in the HTML output. (But if + you're writing your own template, use ``.header`` rather than + ``.verbose_name``) :type accessor: :class:`basestring` or :class:`~.utils.Accessor` :param accessor: An accessor that describes how to extract values for this @@ -96,7 +98,7 @@ class Column(object): """ return self.verbose_name - def render(self, value, **kwargs): + def render(self, value): """ Returns the content for a specific cell. @@ -297,10 +299,11 @@ class TemplateColumn(Column): class BoundColumn(object): """ - A *runtime* version of :class:`.Column`. The difference between - ``BoundColumn`` and ``Column``, is that ``BoundColumn`` objects are of the - relationship between a ``Column`` and a :class:`.Table`. This means that it - knows the *name* given to the ``Column``. + A *run-time* version of :class:`.Column`. The difference between + ``BoundColumn`` and ``Column``, is that ``BoundColumn`` objects include the + relationship between a ``Column`` and a :class:`.Table`. In practice, this + means that a ``BoundColumn`` knows the *"variable name"* given to the + ``Column`` when it was declared on the ``Table``. For convenience, all :class:`.Column` properties are available from this class. @@ -405,11 +408,12 @@ class BoundColumn(object): relationship turns from ORM relationships to object attributes [e.g. person.upper should stop at person]). """ - # Favor an explicit verbose_name + # Favor an explicit defined verbose_name if self.column.verbose_name: return self.column.verbose_name - # Reasonable fallback + # This is our reasonable fallback, should the next section not result + # in anything useful. name = self.name.replace('_', ' ') # Perhap use a model field's verbose_name diff --git a/django_tables2/tables.py b/django_tables2/tables.py index 3bd4c56..abe49de 100644 --- a/django_tables2/tables.py +++ b/django_tables2/tables.py @@ -161,7 +161,11 @@ class DeclarativeColumnsMetaclass(type): attrs["base_columns"] = SortedDict(parent_columns) # Possibly add some generated columns based on a model if opts.model: - extra = SortedDict(((f.name, Column()) for f in opts.model._meta.fields)) + # We explicitly pass in verbose_name, so that if the table is + # instantiated with non-queryset data, model field verbose_names + # are used anyway. + extra = SortedDict(((f.name, Column(verbose_name=f.verbose_name)) + for f in opts.model._meta.fields)) attrs["base_columns"].update(extra) # Explicit columns override both parent and generated columns attrs["base_columns"].update(SortedDict(columns)) diff --git a/tests/columns.py b/tests/columns.py index 8dd7cb6..8767be9 100644 --- a/tests/columns.py +++ b/tests/columns.py @@ -8,10 +8,13 @@ from django.core.exceptions import ImproperlyConfigured import django_tables2 as tables from django_tables2 import utils, A from .testapp.models import Person +from django.utils.translation import ugettext_lazy +from django.utils.translation import ugettext general = Tests() + @general.test def sortable(): class SimpleTable(tables.Table): @@ -33,6 +36,21 @@ def sortable(): Assert(SimpleTable([]).columns['name'].sortable) is True +@general.test +def translation(): + """ + Tests different types of values for the ``verbose_name`` property of a + column. + """ + class TranslationTable(tables.Table): + normal = tables.Column(verbose_name=ugettext("Normal")) + lazy = tables.Column(verbose_name=ugettext("Lazy")) + + table = TranslationTable([]) + Assert("Normal") == table.columns["normal"].header + Assert("Lazy") == table.columns["lazy"].header + + @general.test def sequence(): """ diff --git a/tests/models.py b/tests/models.py index af31126..54d6b87 100644 --- a/tests/models.py +++ b/tests/models.py @@ -100,6 +100,8 @@ def verbose_name(): r1 = tables.Column(accessor='occupation.region.name') r2 = tables.Column(accessor='occupation.region.name.upper') r3 = tables.Column(accessor='occupation.region.name', verbose_name='OVERRIDE') + trans_test = tables.Column() + trans_test_lazy = tables.Column() # The Person model has a ``first_name`` and ``last_name`` field, but only # the ``last_name`` field has an explicit ``verbose_name`` set. This means @@ -122,6 +124,20 @@ def verbose_name(): Assert('Name') == table.columns['r1'].verbose_name Assert('Name') == table.columns['r2'].verbose_name Assert('OVERRIDE') == table.columns['r3'].verbose_name + Assert("Translation Test") == table.columns["trans_test"].verbose_name + Assert("Translation Test Lazy") == table.columns["trans_test_lazy"].verbose_name + + # ------------------------------------------------------------------------- + + # Now we'll try using a table with Meta.model + class PersonTable(tables.Table): + class Meta: + model = Person + # Issue #16 + table = PersonTable([]) + Assert("Translation Test") == table.columns["trans_test"].verbose_name + Assert("Translation Test Lazy") == table.columns["trans_test_lazy"].verbose_name + @models.test def column_mapped_to_nonexistant_field(): diff --git a/tests/testapp/models.py b/tests/testapp/models.py index 700a482..6e675fe 100644 --- a/tests/testapp/models.py +++ b/tests/testapp/models.py @@ -1,4 +1,6 @@ from django.db import models +from django.utils.translation import ugettext_lazy +from django.utils.translation import ugettext class Person(models.Model): @@ -6,6 +8,8 @@ class Person(models.Model): last_name = models.CharField(max_length=200, verbose_name='Surname') occupation = models.ForeignKey('Occupation', related_name='people', null=True, verbose_name='Occupation') + trans_test = models.CharField(max_length=200, blank=True, verbose_name=ugettext("Translation Test")) + trans_test_lazy = models.CharField(max_length=200, blank=True, verbose_name=ugettext("Translation Test Lazy")) def __unicode__(self): return self.first_name -- 2.26.2