diff --git a/django_tables2/columns/base.py b/django_tables2/columns/base.py
index f5edf77f..188138d8 100644
--- a/django_tables2/columns/base.py
+++ b/django_tables2/columns/base.py
@@ -338,6 +338,26 @@ def header(self):
"""
return self.verbose_name
+ @property
+ def header_value(self):
+ """
+ The value used for the column heading in exports.
+
+ By default this returns `~.Column.header`.
+
+ :returns: `unicode` or `None`
+
+ .. note::
+
+ This property typically is not accessed directly when a table is
+ rendered. Instead, `.BoundColumn.header_value` is accessed which
+ in turn accesses this property. This allows the header to fallback
+ to the column name (it is only available on a `.BoundColumn` object
+ hence accessing that first) when this property doesn't return something
+ useful.
+ """
+ return self.header
+
def footer(self, bound_column, table):
"""Return the content of the footer, if specified."""
footer_kwargs = {"column": self, "bound_column": bound_column, "table": table}
@@ -556,6 +576,14 @@ def header(self):
# fall back to automatic best guess
return self.verbose_name
+ @property
+ def header_value(self):
+ """The contents of the header for this column in an export."""
+ column_header_value = self.column.header_value
+ if column_header_value:
+ return column_header_value
+ return self.header
+
@property
def footer(self):
"""The contents of the footer cell for this column."""
diff --git a/django_tables2/tables.py b/django_tables2/tables.py
index f7fcded4..5cc6e550 100644
--- a/django_tables2/tables.py
+++ b/django_tables2/tables.py
@@ -493,7 +493,7 @@ def value_name(self, value):
if not (column.column.exclude_from_export or column.name in exclude_columns)
]
- yield [force_str(column.header, strings_only=True) for column in columns]
+ yield [force_str(column.header_value, strings_only=True) for column in columns]
for row in self.rows:
yield [
diff --git a/docs/pages/custom-data.rst b/docs/pages/custom-data.rst
index adf36c07..565dc764 100644
--- a/docs/pages/custom-data.rst
+++ b/docs/pages/custom-data.rst
@@ -151,9 +151,9 @@ Please refer to `.Table.as_values` for an example.
Subclassing `.Column`
---------------------
-Defining a column subclass allows functionality to be reused across tables.
-Columns have a `render` method that behaves the same as :ref:`table.render_foo`
-methods on tables::
+Defining a column subclass allows further customization and functionality to
+be reused across tables. Columns have a `render` method that behaves the same
+as :ref:`table.render_foo` methods on tables::
>>> import django_tables2 as tables
>>>
@@ -186,3 +186,19 @@ For complicated columns, you may want to return HTML from the
... def render(self, value):
... return format_html('', value)
...
+
+When subclassing a column, the header in the html table can be customized by
+overriding :meth:`~Column.header`. The header value for exports can be independently
+customized using :meth:`~Column.render_value`.
+
+
+ >>> from django.utils.html import format_html
+ >>>
+ >>> class PartyColumn(tables.Column):
+ ... @property
+ ... def header(self):
+ ... return format_html('