Opened 5 years ago

Closed 5 years ago

Last modified 20 months 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: master
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 Changed 5 years ago by Tim Graham

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 Changed 5 years ago by Udi Oron

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 Changed 5 years ago by Tim Graham

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

comment:4 Changed 5 years ago by Ana Balica

Owner: changed from nobody to Ana Balica
Status: newassigned

comment:5 Changed 5 years ago by Tim Graham

Has patch: set
Needs tests: set

PR which needs tests.

comment:6 Changed 5 years ago by Tim Graham

Needs tests: unset
Patch needs improvement: set

Now has tests, but needs some other improvements.

comment:7 Changed 5 years ago by Udi Oron

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

comment:8 Changed 5 years ago by Ana Balica

Patch needs improvement: unset

comment:9 Changed 5 years ago by Markus Holtermann

Triage Stage: AcceptedReady for checkin

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

Resolution: fixed
Status: assignedclosed

In 2f615b10:

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

comment:11 Changed 4 years ago by Claude Paroz <claude@…>

In 742ea514:

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

Thanks Tim Graham for the initial patch.

comment:12 Changed 20 months ago by Tim Graham <timograham@…>

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