Commit 29c1151a authored by Julia Matsieva's avatar Julia Matsieva Committed by Tim Graham
Browse files

Fixed #22756 -- Added view name to technical 404 template if Http404 is raised.

Thanks Keryn Knight for the suggestion.
parent 0b5bafe9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -430,6 +430,7 @@ answer newbie questions, and generally made Django that much better:
    Orestis Markou <orestis@orestis.gr>
    Andrés Torres Marroquín <andres.torres.marroquin@gmail.com>
    Pablo Martín <goinnn@gmail.com>
    Julia Matsieva <julia.matsieva@gmail.com>
    Takashi Matsuo <matsuo.takashi@gmail.com>
    Zlatko Mašek <zlatko.masek@gmail.com>
    Yasushi Masuda <whosaysni@gmail.com>
+26 −1
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ import sys
import types

from django.conf import settings
from django.core.urlresolvers import resolve, Resolver404
from django.http import (HttpResponse, HttpResponseNotFound, HttpRequest,
    build_request_repr)
from django.template import Template, Context, TemplateDoesNotExist
@@ -496,6 +497,23 @@ def technical_404_response(request, exception):
    if isinstance(urlconf, types.ModuleType):
        urlconf = urlconf.__name__

    caller = ''
    try:
        resolver_match = resolve(request.path)
    except Resolver404:
        pass
    else:
        obj = resolver_match.func

        if hasattr(obj, '__name__'):
            caller = obj.__name__
        elif hasattr(obj, '__class__') and hasattr(obj.__class__, '__name__'):
            caller = obj.__class__.__name__

        if hasattr(obj, '__module__'):
            module = obj.__module__
            caller = '%s.%s' % (module, caller)

    t = Template(TECHNICAL_404_TEMPLATE, name='Technical 404 template')
    c = Context({
        'urlconf': urlconf,
@@ -505,6 +523,7 @@ def technical_404_response(request, exception):
        'reason': force_bytes(exception, errors='replace'),
        'request': request,
        'settings': get_safe_settings(),
        'raising_view_name': caller,
    })
    return HttpResponseNotFound(t.render(c), content_type='text/html')

@@ -1093,6 +1112,12 @@ TECHNICAL_404_TEMPLATE = """
        <th>Request URL:</th>
        <td>{{ request.build_absolute_uri|escape }}</td>
      </tr>
      {% if raising_view_name %}
      <tr>
        <th>Raised by:</th>
        <td>{{ raising_view_name }}</td>
      </tr>
      {% endif %}
    </table>
  </div>
  <div id="info">
+11 −0
Original line number Diff line number Diff line
@@ -72,8 +72,19 @@ class DebugViewTests(TestCase):

    def test_404_not_in_urls(self):
        response = self.client.get('/not-in-urls')
        self.assertNotContains(response, "Raised by:", status_code=404)
        self.assertContains(response, "<code>not-in-urls</code>, didn't match", status_code=404)

    def test_technical_404(self):
        response = self.client.get('/views/technical404/')
        self.assertContains(response, "Raised by:", status_code=404)
        self.assertContains(response, "view_tests.views.technical404", status_code=404)

    def test_classbased_technical_404(self):
        response = self.client.get('/views/classbased404/')
        self.assertContains(response, "Raised by:", status_code=404)
        self.assertContains(response, "view_tests.views.Http404View", status_code=404)

    def test_view_exceptions(self):
        for n in range(len(except_args)):
            self.assertRaises(BrokenException, self.client.get,
+3 −0
Original line number Diff line number Diff line
@@ -57,6 +57,9 @@ urlpatterns = [
    url(r'raises404/$', views.raises404),
    url(r'raises500/$', views.raises500),

    url(r'technical404/$', views.technical404, name="my404"),
    url(r'classbased404/$', views.Http404View.as_view()),

    # i18n views
    url(r'^i18n/', include('django.conf.urls.i18n')),
    url(r'^jsi18n/$', i18n.javascript_catalog, js_info_dict),
+12 −1
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@ import sys

from django.core.exceptions import PermissionDenied, SuspiciousOperation
from django.core.urlresolvers import get_resolver
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse, Http404
from django.shortcuts import render_to_response, render
from django.template import Context, RequestContext, TemplateDoesNotExist
from django.views.debug import technical_500_response, SafeExceptionReporterFilter
@@ -16,6 +16,8 @@ from django.views.decorators.debug import (sensitive_post_parameters,
from django.utils._os import upath
from django.utils.log import getLogger

from django.views.generic import View

from . import BrokenException, except_args

dirs = (os.path.join(os.path.dirname(upath(__file__)), 'other_templates'),)
@@ -60,6 +62,15 @@ def raises404(request):
    resolver.resolve('/not-in-urls')


def technical404(request):
    raise Http404("Testing technical 404.")


class Http404View(View):
    def get(self, request):
        raise Http404("Testing class-based technical 404.")


def redirect(request):
    """
    Forces an HTTP redirect.