Ian Ward's email:
first name at this domain
wardi on OFTC, freenode and github
If you've ever wanted to know if a Django template is using a variable it shouldn't be, or not using a variable it should, this code will make both cases fail loudly. Django's default template behaviour is to silently replace missing variables with an empty string, and ignore unused variables.
To use this code you can either:
Paranoid Django Templates Source Code:
class ParanoidKeyError(Exception):
"""
This can't be a KeyError subclass or Django template
rendering will swallow it.
"""
class ParanoidContextProxy(object):
"""
This is a poor-man's proxy for a context instance.
Make sure template rendering stops immediately on a KeyError.
"""
def __init__(self, context):
self.context = context
self.seen_keys = set()
def __getitem__(self, key):
self.seen_keys.add(key)
try:
return self.context[key]
except KeyError:
raise ParanoidKeyError('ParanoidKeyError: %r' % (key,))
def __getattr__(self, name):
return getattr(self.context, name)
def __setitem__(self, key, value):
self.context[key] = value
def __delitem__(self, key):
del self.context[key]
@contextlib.contextmanager
def paranoid_context_manager(context, expected_keys=None):
"""
use ParanoidContextProxy *and* make sure keys in expected_keys iterable
are all referenced inside the with statement.
"""
yield ParanoidContextProxy(context)
if expected_keys:
unref = set(expected_keys).difference(context.seen_keys)
if unref:
raise ParanoidKeyError('Keys not referenced: %r' % (unref,))
def paranoid_render_to_response(template_name, dictionary=None,
context_instance=None, *args, **kwargs):
"""
use ParanoidContextProxy *and* require that all variables passed
in the data dictionary are used by templates at least once.
"""
if dictionary is None:
dictionary = {}
with paranoid_context_manager(context_instance, dictionary.keys()) as c:
return render_to_response(template_name, dictionary, c, *args, **kwargs)
I'll put this up on github once I've written some tests and better docs.