Opened 5 years ago

Closed 5 years ago

#24765 closed Bug (fixed)

Calling flatten on a Context object fails in some cases

Reported by: Dan Poirier Owned by: Buddy Lindsey
Component: Template system Version: 1.8
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

For example, if one of the "dicts" in the Context object is actually a RequestContext. Here's the flatten method in Django 1.8.1 (from django/template/context.py, line 101):

    def flatten(self):
        """
        Returns self.dicts as one dictionary
        """
        flat = {}
        for d in self.dicts:
            flat.update(d)
        return flat

The line flat.update(d) fails because a RequestContext doesn't provide enough of a dictionary's interface to be used in an update, and you get errors like:

    File ".../lib/python2.7/site-packages/django/template/context.py", line 107, in flatten
       flat.update(d)
    ValueError: dictionary update sequence element #0 has length 6; 2 is required

It might be a little tricky to come up with a case where a Context ends up with a RequestContext in it. I believe in my case it's happening when a template uses an inclusion_tag type template tag that returns its context argument, possibly modified, e.g.:

        @register.inclusion_tag('template_fragment.html', takes_context=True)
        def some_tag(context):
            context['thingy'] = 12
            return context

The return value gets pushed onto the Context. During testing, the Context ends up being returned in the list of Context objects in Response.context, which is where I was trying to call flatten on it.

I don't know if the right fix is to make a RequestContext behave more like a dictionary, or to avoid pushing RequestContext objects onto a Context, or something else. I will probably work around for now by forcing the return values from my inclusion_tags to be simple dictionaries.

Context.flatten: https://docs.djangoproject.com/en/1.8/ref/templates/api/#django.template.Context.flatten

Change History (4)

comment:1 Changed 5 years ago by Tim Graham

Triage Stage: UnreviewedAccepted

comment:2 Changed 5 years ago by Buddy Lindsey

Owner: changed from nobody to Buddy Lindsey
Status: newassigned

comment:3 Changed 5 years ago by Tim Graham

Has patch: set
Patch needs improvement: set

I left some comments for improvement on the pull request. poirier, could you check if it solves your problem? I'm not sure if we should add a higher level test for the case presented in the ticket or not.

comment:4 Changed 5 years ago by Tim Graham <timograham@…>

Resolution: fixed
Status: assignedclosed

In ec70437:

Fixed #24765 -- Allowed template context updates to flatten a Context.

Note: See TracTickets for help on using tickets.
Back to Top