Opened 10 years ago

Closed 10 years ago

Last modified 6 years ago

#24829 closed New feature (fixed)

TemplateView raises unhandled ContentNotRenderedError error when used as error handler

Reported by: Udi Oron Owned by: Ana Balica
Component: Generic views Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When using TemplateView for handler403, an unhandled error occurs:

from django.conf.urls import url
from django.core.exceptions import PermissionDenied
from django.views.generic import TemplateView


class PermissionDeniedView(TemplateView):
    template_name = '403.html'


handler403 = PermissionDeniedView.as_view()


def my_view(request):
    raise PermissionDenied


urlpatterns = [
    url(r'^$', my_view),
]

Traceback:

Traceback (most recent call last):
  File "/usr/lib64/python2.7/wsgiref/handlers.py", line 86, in run
    self.finish_response()
  File "/usr/lib64/python2.7/wsgiref/handlers.py", line 127, in finish_response
    for data in self.result:
  File "/home/foo/.virtualenvs/bar/lib/python2.7/site-packages/django/template/response.py", line 171, in __iter__
    raise ContentNotRenderedError('The response content must be '
ContentNotRenderedError: The response content must be rendered before it can be iterated over.
[20/May/2015 07:26:25]"GET / HTTP/1.1" 500 59
Traceback (most recent call last):
  File "/usr/lib64/python2.7/SocketServer.py", line 599, in process_request_thread
    self.finish_request(request, client_address)
  File "/usr/lib64/python2.7/SocketServer.py", line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/home/foo/.virtualenvs/bar/lib/python2.7/site-packages/django/core/servers/basehttp.py", line 102, in __init__
    super(WSGIRequestHandler, self).__init__(*args, **kwargs)
  File "/usr/lib64/python2.7/SocketServer.py", line 655, in __init__
    self.handle()
  File "/home/foo/.virtualenvs/bar/lib/python2.7/site-packages/django/core/servers/basehttp.py", line 182, in handle
    handler.run(self.server.get_app())
  File "/usr/lib64/python2.7/wsgiref/handlers.py", line 92, in run
    self.close()
  File "/usr/lib64/python2.7/wsgiref/simple_server.py", line 33, in close
    self.status.split(' ',1)[0], self.bytes_sent
AttributeError: 'NoneType' object has no attribute 'split'

One workaround is to force TemplateResponse to render itself:

class PermissionDeniedView(TemplateView):
    template_name = '403.html'

    def dispatch(self, request, *args, **kwargs):
        response = super(PermissionDeniedView, self).dispatch(request, *args, **kwargs)
        response.render()
        return response

Change History (12)

comment:1 by Tim Graham, 10 years ago

Summary: TemplateView raises unhandled ContentNotRenderedError error when used as handler403TemplateView raises unhandled ContentNotRenderedError error when used as error handler
Triage Stage: UnreviewedAccepted
Type: BugNew feature
Version: 1.8master

I'm wondering if you have a compelling use case for class-based views as error handlers? Your example reproduces the default view as far as I can tell. I'm not sure what changes would be required to support this, but I'd think it would be nice to keep the error handling code as simple as possible. That said, if we decide not to fix this we should at least document the restriction.

comment:2 by Udi Oron, 10 years ago

Regarding use case - our "permission denied" page includes the complete site layout - including navigation and user information resolved at a site wide mixin used also in the PermissionDeniedView.

Examining the source code of SimpleTemplateResponse, one solution could be removing ContentNotRenderedError, and call self.render() instead of raising it:

if not self._is_rendered:
    self.render()

Why is ContentNotRenderedError needed?

comment:3 by Tim Graham, 10 years ago

Did you try making the change you suggested and then looking at what tests fail? That usually gives some insight.

comment:4 by Ana Balica, 10 years ago

Owner: changed from nobody to Ana Balica
Status: newassigned

comment:5 by Tim Graham, 10 years ago

Has patch: set
Needs tests: set

PR which needs tests.

comment:6 by Tim Graham, 10 years ago

Needs tests: unset
Patch needs improvement: set

Now has tests, but needs some other improvements.

comment:7 by Udi Oron, 10 years ago

Regarding the suggested fix, instead of fixing the handler, shouldn't this be considered as a TemplateResponse / TemplateView problem?

comment:8 by Ana Balica, 10 years ago

Patch needs improvement: unset

comment:9 by Markus Holtermann, 10 years ago

Triage Stage: AcceptedReady for checkin

comment:10 by Tim Graham <timograham@…>, 10 years ago

Resolution: fixed
Status: assignedclosed

In 2f615b10:

Fixed #24829 -- Allowed use of TemplateResponse in view error handlers.

comment:11 by Claude Paroz <claude@…>, 9 years ago

In 742ea514:

Refs #24829 -- Made TemplateResponse.content available sooner in exception context

Thanks Tim Graham for the initial patch.

comment:12 by Tim Graham <timograham@…>, 6 years ago

In bff5ccff:

Refs #24829 -- Removed TemplateResponse rendering in BaseHandler.get_response().

Obsolete since 742ea51413b3aab07c6afbfd1d52c1908ffcb510.

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