2009-10-25 17 views
13

Tengo un proyecto en el que estoy trabajando en django. Hay una gran cantidad de casos en los que:¿Cómo mostrar el mensaje pasado a Http404 en una plantilla de error 404 personalizada en Django?

raise Http404("this is an error") 

y crea una agradable página 404 para mí con el mensaje de error "esto es un error" escrito en él.

Ahora quiero crear una página de error personalizada y que siga mostrando el mensaje, pero no puedo entender cómo.

Estoy seguro de que es solo una variable de plantilla que necesito agregar a mi plantilla 404 personalizada, pero no puedo encontrar ninguna documentación para ella.

+0

tiene que encuentre el camino de conseguir "esto es un error" mensaje en la costumbre ¿Controlador 404? @Alasdair, nbv4 realmente le pediré ayuda. – marianobianchi

+0

@marianobianchi Dije erróneamente que sería posible usar un controlador 404 personalizado para lograr esto, pero en realidad no es posible. Hubo una [solicitud de extracción] (https://github.com/django/django/pull/1397) para un cambio requerido, pero fue rechazada. Después de pensarlo, estoy de acuerdo con la decisión. Creo que es mejor usar el marco de mensajes como lo sugiere Euribates, o presentar una plantilla personalizada y devolver el estado 404. Si incluye los mensajes de excepción en la plantilla 404 predeterminada, existe el riesgo de que muestre mensajes de error inadecuados a los usuarios finales. – Alasdair

Respuesta

8

A partir de Django 1.9, la excepción se pasa a la vista page_not_found que se ejecuta cuando sube Http404. Una representación del error se pasa a la plantilla, puede incluirlo en su plantilla con:

{{ exception }} 

En versiones anteriores, la excepción no fue pasado a la vista page_not_found, así que no había una manera fácil incluir el mensaje de la excepción en la plantilla.

Una posibilidad era utilizar el marco de mensajes como @Euribates sugiere en su respuesta. Otra era representar una plantilla y devolver un código de estado 404 en su vista, en lugar de aumentar Http404.

+0

Esto ha cambiado desde 1.9.6: ahora 'exception' contiene el mensaje: http://stackoverflow.com/a/37109914/895245 –

+0

' {{exception}} 'solo representa un mensaje personalizado establecido en la vista si' DEPURADOR 'está establecido en 'True'. Si 'DEBUG = False', entonces' {{exception}} 'usado en 404.html simplemente renderiza" Http404 ". –

6

Hay otra manera. El código en page_not_found usa 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, los marcos django .

Por lo tanto, defina el mensaje que desea mostrar usando messages.error, por ejemplo, y muestre el mensaje en la plantilla utilizando la variable messages.

En otras palabras, usted puede escribir su vista como esta:

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 su plantilla 404.html, usted debe 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 utilizar diferentes tipos de mensajes (Advertencia, Depuración, Información, Error, etc.). Puede leer más sobre el marco de trabajo de django aquí: The messages framework | Django Documentation.

1

que tenemos una solución más simple

Sólo tiene que escribir middleware, que llevaría el texto de error en alguna variable petición. 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 }} 
Cuestiones relacionadas