3
votes

When i override the handler404 and handler500 in my urls.py like so:

from myapp.views import not_found_view

handler404 = not_found_view
handler500 = not_found_view

and call raise Http404() in my middleware, i see my 404 page.

When i remove both handler404 and handler500 from my urls.py and raise Http404() in my middleware, i see my default 500 error page (from Django Suit) - hence the reason i'm trying to set a custom 404 template to be used on raise Http404()'s.

Now my problem: when i remove the handler500 and only set the handler404, i also get to see a HTTP 500 page! :|

Why is my handler500 called when i raise Http404() ??

I have multiple template directories in multiple apps, i tried placing a 404.html in my main app that contains the settings and in another 'normal' app but that didn't work..

I've set DEBUG to False as well.

Hope someone can answer my question!

4

4 Answers

10
votes

You don't have to write your own handlers if you just want to replace Django's template. Django uses 404.html and 500.html files for templates and you can replace them with putting file with same name to the directory listed in settings.TEMPLATE_DIRS.

In your example that means that you can create myapp/templates/404.html and myapp/templates/500.html files.

Note that you have to set DEBUG to False to se those templates.

Check this article for mor details.

1
votes

I ran into a similar situation. My custom handler404 WAS being called, yet my browser response showed the error500.

Upon inspection, I found I had a syntax error in the template. Thus, the 500 was being caused by that. I fixed the template and the result was as desired.

The catch 22 is that by default, template debug == debug, so if you set DEBUG=False then the template debug will be false as well; you'll see the 500 error without the template error trace.

So, place a print() statement in your handler404 view, right before returning render() . If you see the output in your django console, you'll know the error is in your template.

You could also try this in your settings.py (django 1.8+) but this didn't seem to work for me, and I didn't follow through once I fixed the template.

TEMPLATES = [
    {

        'OPTIONS': {
             'debug': True,
         }
    },
0
votes

Another solution is to replace (monkey-patch) Django's page_not_found.

from django.views import defaults
from myapp.views import not_found_view

defaults.page_not_found = not_found_view

Monkey-patching is bad practice and may stop working if Django updates internal API, but still may be useful in some situations. Ex. if other methods don't work on some reason.

0
votes

The 404-page-not-found-view needs an "exception" argument:

def handler404(request, exception):
    return render(request, 'customer/home_page/404.html', status=404)