Comment afficher le message transmis à Http404 dans un modèle d'erreur 404 personnalisé dans Django?
-
06-07-2019 - |
Question
J'ai un projet sur lequel je travaille à Django. Il y a beaucoup de cas où je:
raise Http404("this is an error")
et cela crée pour moi une belle page 404 avec le message d'erreur "ceci est une erreur". écrit dessus.
Je souhaite maintenant créer une page d'erreur personnalisée et l'afficher tout de même, mais je ne vois pas comment.
Je suis sûr qu'il ne s'agit que d'une variable de modèle que je dois ajouter à mon modèle 404 personnalisé, mais je ne trouve aucune documentation à ce sujet.
La solution
À partir de Django 1.9, l'exception est transmise à page_not_found
vue qui s'exécute lorsque vous générez Http404
. Une représentation de l'erreur est transmise au modèle, vous pouvez l'inclure dans votre modèle avec:
{{ exception }}
Dans les versions précédentes, l'exception n'était pas transmise à la vue page_not_found
. Il n'était donc pas facile d'inclure le message de l'exception dans le modèle.
Une possibilité consistait à utiliser le cadre des messages comme le suggère @Euribates dans leur réponse. Une autre solution consistait à générer un modèle et à renvoyer un code d'état 404 dans votre vue, au lieu de générer Http404
.
Autres conseils
Il existe un autre moyen. Le code situé dans page_not_found
utilise RequestContext
; cela signifie que vous avez accès à toutes les variables définies par tous les processeurs de contexte définis dans l'entrée TEMPLATE_CONTEXT_PROCESSORS
dans settings.py
. La valeur par défaut inclut, entre autres, le framework messages de Django.
Ainsi, vous pouvez définir le message que vous souhaitez afficher à l'aide de messages.error
, par exemple, et affichez le message dans le modèle à l'aide de la variable messages
.
En d'autres termes, vous pouvez écrire votre vue de la manière suivante:
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()),
)
Dans votre modèle 404.html, vous devriez écrire quelque chose comme:
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
C’est un peu plus complexe, mais cela présente l’avantage de pouvoir envoyer plusieurs messages et même utiliser différents types de messages (Avertissement, Débogage, Info, Erreur, etc.). Vous pouvez en savoir plus sur le cadre de messages Django. ici: Le cadre de messagerie | Documentation Django .
j'ai une solution plus simple
Il suffit d'écrire le middleware, cela prendrait votre texte d'erreur dans une variable de requête. Voir exemple
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
In 404.html
{{ request.error_404_message }}
{{exception}}
À partir de la version 1.9.6, le message transmis à:
raise Http404('msg')
est disponible à partir de templates / 404.html
en tant que:
{{ exception }}
Source: https: // github. com / django / django / blob / 1.9.6 / django / views / defaults.py # L20