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.

Reply via email to