import urllib
import tokenize
import StringIO
+from django.conf import settings
from django import template
from django.template.loader import get_template
from django.utils.safestring import mark_safe
self.table_var = template.Variable(table_var_name)
def render(self, context):
- table = self.table_var.resolve(context)
- if 'request' not in context:
- raise AssertionError('{% render_table %} requires that the '
- 'template context contains the HttpRequest in'
- ' a "request" variable, check your '
- ' TEMPLATE_CONTEXT_PROCESSORS setting.')
- context = template.Context({'request': context['request'], 'table': table})
try:
- table.request = context['request']
- return get_template('django_tables/table.html').render(context)
- finally:
- del table.request
+ # may raise VariableDoesNotExist
+ table = self.table_var.resolve(context)
+ if "request" not in context:
+ raise AssertionError("{% render_table %} requires that the "
+ "template context contains the HttpRequest in"
+ " a 'request' variable, check your "
+ " TEMPLATE_CONTEXT_PROCESSORS setting.")
+ context = template.Context({"request": context["request"],
+ "table": table})
+ try:
+ table.request = context["request"]
+ return get_template("django_tables/table.html").render(context)
+ finally:
+ del table.request
+ except:
+ if settings.DEBUG:
+ raise
+ else:
+ return settings.TEMPLATE_STRING_IF_INVALID
@register.tag
# -*- coding: utf8 -*-
-"""Test template specific functionality.
-
-Make sure tables expose their functionality to templates right. This
-generally about testing "out"-functionality of the tables, whether
-via templates or otherwise. Whether a test belongs here or, say, in
-``test_basic``, is not always a clear-cut decision.
-"""
-
-from django.template import Template, Context
+from django.template import Template, Context, VariableDoesNotExist
from django.http import HttpRequest
+from django.conf import settings
import django_tables as tables
from attest import Tests, Assert
from xml.etree import ElementTree as ET
+
templates = Tests()
-@templates.context
-def context():
- class Context(object):
- class CountryTable(tables.Table):
- name = tables.Column()
- capital = tables.Column(sortable=False)
- population = tables.Column(verbose_name='Population Size')
- currency = tables.Column(visible=False)
- tld = tables.Column(visible=False, verbose_name='Domain')
- calling_code = tables.Column(accessor='cc',
- verbose_name='Phone Ext.')
-
- data = [
- {'name': 'Germany', 'capital': 'Berlin', 'population': 83,
- 'currency': 'Euro (€)', 'tld': 'de', 'cc': 49},
- {'name': 'France', 'population': 64, 'currency': 'Euro (€)',
- 'tld': 'fr', 'cc': 33},
- {'name': 'Netherlands', 'capital': 'Amsterdam', 'cc': '31'},
- {'name': 'Austria', 'cc': 43, 'currency': 'Euro (€)',
- 'population': 8}
- ]
- yield Context
+class CountryTable(tables.Table):
+ name = tables.Column()
+ capital = tables.Column(sortable=False)
+ population = tables.Column(verbose_name='Population Size')
+ currency = tables.Column(visible=False)
+ tld = tables.Column(visible=False, verbose_name='Domain')
+ calling_code = tables.Column(accessor='cc',
+ verbose_name='Phone Ext.')
+
+
+MEMORY_DATA = [
+ {'name': 'Germany', 'capital': 'Berlin', 'population': 83,
+ 'currency': 'Euro (€)', 'tld': 'de', 'cc': 49},
+ {'name': 'France', 'population': 64, 'currency': 'Euro (€)',
+ 'tld': 'fr', 'cc': 33},
+ {'name': 'Netherlands', 'capital': 'Amsterdam', 'cc': '31'},
+ {'name': 'Austria', 'cc': 43, 'currency': 'Euro (€)',
+ 'population': 8}
+]
@templates.test
-def as_html(context):
- table = context.CountryTable(context.data)
- root = ET.fromstring(table.as_html())
+def as_html():
+ table = CountryTable(MEMORY_DATA)
+ root = ET.fromstring(table.as_html())
Assert(len(root.findall('.//thead/tr'))) == 1
Assert(len(root.findall('.//thead/tr/th'))) == 4
Assert(len(root.findall('.//tbody/tr'))) == 4
Assert(len(root.findall('.//tbody/tr/td'))) == 16
-
+
# no data with no empty_text
- table = context.CountryTable([])
+ table = CountryTable([])
root = ET.fromstring(table.as_html())
Assert(1) == len(root.findall('.//thead/tr'))
Assert(4) == len(root.findall('.//thead/tr/th'))
Assert(0) == len(root.findall('.//tbody/tr'))
-
+
# no data WITH empty_text
- table = context.CountryTable([], empty_text='this table is empty')
+ table = CountryTable([], empty_text='this table is empty')
root = ET.fromstring(table.as_html())
Assert(1) == len(root.findall('.//thead/tr'))
Assert(4) == len(root.findall('.//thead/tr/th'))
@templates.test
-def custom_rendering(context):
+def custom_rendering():
"""For good measure, render some actual templates."""
- countries = context.CountryTable(context.data)
+ countries = CountryTable(MEMORY_DATA)
context = Context({'countries': countries})
# automatic and manual column verbose names
@templates.test
-def templatetag(context):
+def templatetag():
# ensure it works with a multi-order-by
- table = context.CountryTable(context.data, order_by=('name', 'population'))
+ table = CountryTable(MEMORY_DATA, order_by=('name', 'population'))
t = Template('{% load django_tables %}{% render_table table %}')
html = t.render(Context({'request': HttpRequest(), 'table': table}))
-
- root = ET.fromstring(html)
+
+ root = ET.fromstring(html)
Assert(len(root.findall('.//thead/tr'))) == 1
Assert(len(root.findall('.//thead/tr/th'))) == 4
Assert(len(root.findall('.//tbody/tr'))) == 4
Assert(len(root.findall('.//tbody/tr/td'))) == 16
-
+
# no data with no empty_text
- table = context.CountryTable([])
+ table = CountryTable([])
t = Template('{% load django_tables %}{% render_table table %}')
html = t.render(Context({'request': HttpRequest(), 'table': table}))
- root = ET.fromstring(html)
+ root = ET.fromstring(html)
Assert(len(root.findall('.//thead/tr'))) == 1
Assert(len(root.findall('.//thead/tr/th'))) == 4
Assert(len(root.findall('.//tbody/tr'))) == 0
-
+
# no data WITH empty_text
- table = context.CountryTable([], empty_text='this table is empty')
+ table = CountryTable([], empty_text='this table is empty')
t = Template('{% load django_tables %}{% render_table table %}')
html = t.render(Context({'request': HttpRequest(), 'table': table}))
- root = ET.fromstring(html)
+ root = ET.fromstring(html)
Assert(len(root.findall('.//thead/tr'))) == 1
Assert(len(root.findall('.//thead/tr/th'))) == 4
Assert(len(root.findall('.//tbody/tr'))) == 1
Assert(len(root.findall('.//tbody/tr/td'))) == 1
Assert(int(root.find('.//tbody/tr/td').attrib['colspan'])) == len(root.findall('.//thead/tr/th'))
Assert(root.find('.//tbody/tr/td').text) == 'this table is empty'
-
-
-
+
+ # variable that doesn't exist (issue #8)
+ t = Template('{% load django_tables %}{% render_table this_doesnt_exist %}')
+ with Assert.raises(VariableDoesNotExist):
+ settings.DEBUG = True
+ t.render(Context())
+
+ # Should be silent with debug off
+ settings.DEBUG = False
+ t.render(Context())