Opened 9 years ago

Closed 9 years ago

#24960 closed Bug (fixed)

Blank pages due to {{ block.super }}

Reported by: Sven R. Kunze Owned by: nobody
Component: Template system Version: dev
Severity: Normal Keywords: block.super blank pages
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: yes

Description (last modified by Sven R. Kunze)

When using {{ block.super }}, it behaves like a normal variable which leads to the following issue:

As soon as the block.super raises (e.g.) a UnicodeDecodeError, {{ block.super }} evaluates to an empty string.

When using {{ block.super }} in cascading base templates, this frequently leads to blank pages which are hard to debug.

Change History (13)

comment:1 by Sven R. Kunze, 9 years ago

Description: modified (diff)
Keywords: UnicodeDecodeError added; UnicodeEncodeError removed
Summary: {{ block.super }} hides UnicodeEncodeErrors{{ block.super }} hides UnicodeDecodeErrors

comment:2 by Sven R. Kunze, 9 years ago

Description: modified (diff)
Keywords: blank pages added; UnicodeDecodeError removed
Summary: {{ block.super }} hides UnicodeDecodeErrorsBlank pages due to {{ block.super }}

comment:3 by Tim Graham, 9 years ago

Resolution: worksforme
Status: newclosed

I couldn't reproduce this. We'll need more details such as a sample project that reproduces the error. I got a yellow "debug page" when DEBUG=True and a 500 error page when DEBUG=False. Thanks.

comment:4 by Sven R. Kunze, 9 years ago

Resolution: worksforme
Status: closednew

We created a minimal working example:

t1.html, t2.html << base templates
t3.html << example page using failing tag
t4.html << example page using failing variable << example tag; you need to put this file into a working templatestag folder in a working Django app << run this to see the results
test_output.txt << test output rendering t3.html and t4.html

As you can see, t3.html and t4.html yields different results, although the only difference is the usage of tags vs. variables.

The reason for this is the {{ block.super }} variable that returns just an empty string

Last edited 9 years ago by Sven R. Kunze (previous) (diff)

comment:5 by Tim Graham, 9 years ago

Thanks for the example code, however, when I put those render_to_string() calls into views like this:

def t3(request):
    return render_to_string('t3.html')

def t4(request):
    return render_to_string('t4.html', {'error': Error})

I get a yellow debug page in both cases. What behavior do you see? Do you have DEBUG=True? Are you testing with master or some older version of Django?

comment:6 by Sven R. Kunze, 9 years ago

Are you sure that render_to_string(...) works as intended here? Should a view not return a HttpResponse?

We used Django 1.6. We upgraded to Django 1.8 and it seems as if the error is returned properly now.

We looked into the corresponding Django source code and found that Django catches more errors as before and re-raises them. That approach seems a bit error-prone especially when using custom exceptions.

Don't you think that a check whether a context variable is callable/has attribute/has dictionary key should be handled not by trial-and-error but by a check-before-do?

Last edited 9 years ago by Sven R. Kunze (previous) (diff)

comment:7 by Tim Graham, 9 years ago

Yes, my usage of render_to_string() isn't proper, but it seemed enough to test the code you provided.

I'm not following what you are saying now. Django 1.8 fixes the original issue but there's another issue there? Please clarify what behavior you are seeing and what the expected behavior is.

comment:8 by Sven R. Kunze, 9 years ago

In Django 1.6, render_to_string does not work. Maybe, in Django 1.8 this is also another convenience layer.

Well, not sure if Django 1.8 fixes the original issue. Infact, when programming, we simply do not know which errors might occur. So, just because Django re-raises TypeErrors now, does not necessarily mean that we cover all cases (all types of errors).

As soon as somebody raises another exception that is not covered, we are going to see a blank page again. So, our suggestion was: why not check if the given context variable might work in the first place?

Right now, all Django versions just call the variables, do the attribute, do the list access etc. So, we mix up both cases:

  1. wrong access or
  2. internal error when evaluating


We actually do not want an ever-growing list of Errors (TypeError, AttributeError, KeyError, ValueError, IndexError -- as you can see in but a clean long-lasting solution.

For instance, Python provides the function 'hasattr' which can be used to check whether an object has a certain attribute or not. The same goes for list access and function calls.

Last edited 9 years ago by Sven R. Kunze (previous) (diff)

comment:9 by Baptiste Mispelon, 9 years ago

For reference, I bisected the fix down to 28a571348bca9c5a3c137e495e7d3c9349a5bd56 which was a fix for #20745.

comment:10 by Tim Graham, 9 years ago

I still haven't managed to reproduce the "blank page" issue. Could you given an example?

comment:11 by Sven R. Kunze, 9 years ago

Thanks @bmispelon. TypeError was just a quick example. See comment:8, we actually do not appreciate the trial-and-error approach that will lead to an ever-growing except list.

I inspected the commit and it seems it works as intended. I will come back tomorrow and tell you want we find out and may close this issue.

Thanks so far for your support on this.

Last edited 9 years ago by Sven R. Kunze (previous) (diff)

comment:12 by Sven R. Kunze, 9 years ago

@timgraham We see if we can produce an example for 1.8.

comment:13 by Sven R. Kunze, 9 years ago

Resolution: fixed
Status: newclosed

We further investigated the issue. We found that with an upgrade to 1.8, we might resolve the issue of empty {{ block.super }}.

However, we might consider opening another issue for the inconsistencies of variable resolution. We still would prefer a check-if-possible approach instead of try-and-fail.

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