Hello everyone,
while writing a test for a view, I found that one of the rendered templates
context had a key used by the main template of the view itself, but with a
different value.
Given the rendering order, calling
response.context[key]
would not return the view template context value, but the included template
one.
Let me write some code to help myself explaining:
def my_view(request):
context = {'foo': 'bar'}
template = 'my_template.html'
return render_to_response(template, context)
def test_my_view(self):
url = reverse('url_pattern_name')
response = self.client.get(url)
self.assertEqual(response.context['foo'], 'bar') # Fails, due to
another template rendered in my_template redefine 'foo'
So I was wondering whether it might be useful to enrich the ContextList
object by annotating somehow the template name for each sub context.
The *store_rendered_templates* method in django/test/client.py seems the
right place to do it, as it receives both the template and the context:
def store_rendered_templates(store, signal, sender, template, context, **
kwargs):
"""
Stores templates and contexts that are rendered.
The context is copied so that it is an accurate representation at the
time
of rendering.
"""
store.setdefault('templates', []).append(template)
store.setdefault('context', ContextList()).append({template.name: copy(
context)})
and of course the ContextList class has to be modified as well:
class ContextList(list):
"""A wrapper that provides direct key access to context items contained
in a list of context objects.
"""
def __getitem__(self, key):
if isinstance(key, six.string_types):
for template_context in self:
for subcontext in template_context.itervalues():
if key in subcontext:
return subcontext[key]
raise KeyError(key)
else:
return super(ContextList, self).__getitem__(key)
def __contains__(self, key):
try:
self[key]
except KeyError:
return False
return True
def keys(self):
"""
Flattened keys of subcontexts.
"""
keys = set()
for template_context in self:
for subcontext in template_context.itervalues():
for dict in subcontext:
keys |= set(dict.keys())
return keys
def get_for_template(self, template_name):
# Cannot use self[template_name] because of __getitem__
for template_context in self:
if template_context.keys()[0] == template_name:
return template_context.values()[0]
raise KeyError
The implementation is a bit cumbersome because ContextList should be a
ContextDict instead, but that should do the trick nonetheless.
What do you think about it?
Thanks,
Germano
--
You received this message because you are subscribed to the Google Groups
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-developers/be5c3b45-1438-4cef-9a70-dbb031717731%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.