Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display the message passed to Http404 in a custom 404 Error template in Django?

I have a project that I am working on in django. There are a lot of instances where I:

raise Http404("this is an error")

and it creates a nice 404 page for me with the error message "this is an error" written on it.

I now want to create a custom error page and have it still display the message, but I can't figure out how.

I'm sure it's just a template variable that I need to add to my custom 404 template, but I can't find any documentation for it.

like image 380
priestc Avatar asked Oct 25 '09 15:10

priestc


People also ask

How do I return a 404 response code in Django?

To return 404 in Django Framework, you should include the Http404 exception and raise it within a view function. Also you can use get_object_or_404 function from django.


2 Answers

As of Django 1.9, the exception is passed to the page_not_found view which runs when you raise Http404. A representation of the error is passed to the template, you can include it in your template with:

{{ exception }}

In earlier versions, the exception was not passed to the page_not_found view, so there wasn't an easy way to include the message from the exception in the template.

One possibility was to use the messages framework as @Euribates suggests in their answer. Another was to render a template and return a 404 status code in your view, instead of raising Http404.

like image 96
Alasdair Avatar answered Sep 27 '22 21:09

Alasdair


There is another way. The code at page_not_found uses RequestContext; that means that you have access to all the variables defined by all the context processors defined in the TEMPLATE_CONTEXT_PROCESSORS entry in settings.py. The default value includes, among others, the django messages framework.

So, you con define the message you want to show using messages.error, for example, and show the message in the template using the messages variable.

In other words, you can write your view like this:

from django.contrib import messages
from django.http import Http404
from django.template import RequestContext

def my_view(request):
    # your code goes here
    if something_horribly_wrong_happened():
        messages.error(request, 'Somethig horribly wrong happened!')
        raise Http404("It doesn't mind whatever you put here")
    else:
        return render_to_response(
            'template.html',
            RequestContext(request, locals()),
            )

In your 404.html template, you should write something like:

{% if messages %}
<ul class="messages">
    {% for message in messages %}
    <li>{{ message }}</li>
    {% endfor %}
</ul>
{% endif %}

It's a bit more complex, but it has the advantage you can send several messages, and even use diferent kind of messages (Warning, Debug, Info, Error, etc...) You can read more about the django message framework here: The messages framework | Django Documentation.

like image 42
Euribates Avatar answered Sep 27 '22 21:09

Euribates