: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
"""
return self.verbose_name
- def render(self, value, **kwargs):
+ def render(self, value):
"""
Returns the content for a specific cell.
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.
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
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))
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):
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():
"""
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
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():
from django.db import models
+from django.utils.translation import ugettext_lazy
+from django.utils.translation import ugettext
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