#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 , 9 years ago
Summary: | TemplateView raises unhandled ContentNotRenderedError error when used as handler403 → TemplateView raises unhandled ContentNotRenderedError error when used as error handler |
---|---|
Triage Stage: | Unreviewed → Accepted |
Type: | Bug → New feature |
Version: | 1.8 → master |
comment:2 by , 9 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 , 9 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 , 9 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:6 by , 9 years ago
Needs tests: | unset |
---|---|
Patch needs improvement: | set |
Now has tests, but needs some other improvements.
comment:7 by , 9 years ago
Regarding the suggested fix, instead of fixing the handler, shouldn't this be considered as a TemplateResponse / TemplateView problem?
comment:8 by , 9 years ago
Patch needs improvement: | unset |
---|
comment:9 by , 9 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
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.