Fixed issue #8 where a TemplateSyntaxError would be raised when using {% render_table...
authorBradley Ayers <bradley.ayers@gmail.com>
Thu, 2 Jun 2011 23:04:38 +0000 (09:04 +1000)
committerBradley Ayers <bradley.ayers@gmail.com>
Thu, 2 Jun 2011 23:04:38 +0000 (09:04 +1000)
django_tables/templatetags/django_tables.py
tests/templates.py

index b455eaee0dd0ca08629a9ef9d2b869e582f3888c..1166a3de3ccf68dc56c745b3071c5ffa73bd7339 100644 (file)
@@ -14,6 +14,7 @@ Examples:
 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
@@ -89,18 +90,26 @@ class RenderTableNode(template.Node):
         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
index 2a5f482d6ae9fb8bd05e4eb8d728d2edba318e58..6831919f33ad0c68a05f04a37bfac4e71156202e 100644 (file)
@@ -1,63 +1,54 @@
 # -*- 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'))
@@ -68,9 +59,9 @@ def as_html(context):
 
 
 @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
@@ -89,38 +80,45 @@ def custom_rendering(context):
 
 
 @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())