¿Cómo mostrar el mensaje pasado a Http404 en una plantilla de error 404 personalizada en Django?
-
06-07-2019 - |
Pregunta
Tengo un proyecto en el que estoy trabajando en django. Hay muchos casos en los que:
raise Http404("this is an error")
y crea una bonita página 404 para mí con el mensaje de error " este es un error " escrito en él.
Ahora quiero crear una página de error personalizada y seguir mostrando el mensaje, pero no puedo entender cómo.
Estoy seguro de que es solo una variable de plantilla que debo agregar a mi plantilla 404 personalizada, pero no puedo encontrar ninguna documentación para ello.
Solución
A partir de Django 1.9, la excepción se pasa a page_not_found
que se ejecuta cuando eleva Http404
. Una representación del error se pasa a la plantilla, puede incluirla en su plantilla con:
{{ exception }}
En versiones anteriores, la excepción no se pasó a la vista page_not_found
, por lo que no había una manera fácil de incluir el mensaje de la excepción en la plantilla.
Una posibilidad era usar el marco de mensajes como sugiere @Euribates en su respuesta. Otro fue renderizar una plantilla y devolver un código de estado 404 en su vista, en lugar de aumentar Http404
.
Otros consejos
Hay otra manera. El código en page_not_found
utiliza RequestContext
; eso significa que tiene acceso a todas las variables definidas por todos los procesadores de contexto definidos en la entrada TEMPLATE_CONTEXT_PROCESSORS
en settings.py
. El valor predeterminado incluye, entre otros, el marco de django mensajes .
Por lo tanto, puede definir el mensaje que desea mostrar usando messages.error
, por ejemplo, y mostrar el mensaje en la plantilla usando la variable messages
.
En otras palabras, puedes escribir tu vista de esta manera:
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()),
)
En tu plantilla 404.html, deberías escribir algo como:
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
Es un poco más complejo, pero tiene la ventaja de que puede enviar varios mensajes, e incluso usar diferentes tipos de mensajes (Advertencia, Depuración, Información, Error, etc.). Puede leer más sobre el marco de mensajes de Django. Aquí: El marco de mensajes | Documentación Django .
Tengo una solución más simple
Simplemente escriba middleware, eso llevaría su texto de error a alguna variable de solicitud. Ver ejemplo
from django.http.response import Http404
class Error404Middleware(object):
def process_exception(self, request, exception):
if isinstance(exception, Http404):
request.error_404_message = exception.message
En 404.html
{{ request.error_404_message }}
{{exception}}
A partir de 1.9.6, el mensaje pasó a:
raise Http404('msg')
está disponible en templates / 404.html
como:
{{ exception }}
Fuente: https: // github. com / django / django / blob / 1.9.6 / django / views / defaults.py # L20