2009-10-25 9 views
13

Mam projekt, nad którym pracuję w django. Istnieje wiele przypadków, gdzie:Jak wyświetlić komunikat przekazany do Http404 w niestandardowym szablonie błędów 404 w Django?

raise Http404("this is an error") 

i tworzy miłą stronę 404 na mnie z komunikatem o błędzie „To błąd” na niej napisane.

Teraz chcę utworzyć niestandardową stronę błędu i nadal wyświetlać komunikat, ale nie wiem, jak to zrobić.

Jestem pewien, że to tylko zmienna szablonu, którą muszę dodać do mojego niestandardowego szablonu 404, ale nie mogę znaleźć dla niej żadnej dokumentacji.

+0

mają znaleźć sposób na uzyskanie "to błąd" wiadomość w zwyczaju 404 handler? @Alasdair, nbv4 Naprawdę apretiate twojej pomocy. – marianobianchi

+0

@marianobianchi Pomyłkowo powiedziałem, że byłoby możliwe użycie niestandardowego programu obsługi 404, aby to osiągnąć, ale nie jest to faktycznie możliwe. Wystąpiło żądanie pobrania (https://github.com/django/django/pull/1397) dla wymaganej zmiany, ale zostało wyłączone. Po przemyśleniu tego, zgadzam się z decyzją. Myślę, że lepiej jest użyć struktury komunikatów, jak sugeruje program Euribates, lub wyrenderować niestandardowy szablon i zwrócić status 404. Jeśli uwzględnimy komunikaty o wyjątkach w domyślnym szablonie 404, istnieje ryzyko, że użytkownicy będą wyświetlać nieodpowiednie komunikaty o błędach. – Alasdair

Odpowiedz

8

Od wersji Django 1.9 wyjątek jest przekazywany do widoku page_not_found, który jest uruchamiany po podniesieniu Http404. Reprezentacja błędu jest przekazywany do matrycy, można umieścić go w szablonie z:

{{ exception }} 

We wcześniejszych wersjach, wyjątek nie został przekazany do widoku page_not_found, więc nie było łatwym sposobem dołącz wiadomość od wyjątku do szablonu.

Jedną z możliwości było wykorzystanie struktury komunikatów, jak sugeruje @Euribates w ich odpowiedzi. Innym było zrenderowanie szablonu i zwrócenie kodu statusu 404 w widoku, zamiast podnoszenia Http404.

+0

Zmieniło się to z 1.9.6: teraz 'wyjątek' zawiera komunikat: http://stackoverflow.com/a/37109914/895245 –

+0

' {{exception}} 'renderuje tylko dowolny niestandardowy zestaw komunikatów w widoku, jeśli' DEBUG' ma wartość 'True'. Jeśli 'DEBUG = False', to' {{exception}} 'użyte w 404.html po prostu wyświetla" Http404 ". –

6

Jest inny sposób. Kod pod numerem page_not_found używa RequestContext; oznacza to, że masz dostęp do wszystkich zmiennych zdefiniowanych przez wszystkie procesory kontekstowe zdefiniowane w pozycji TEMPLATE_CONTEXT_PROCESSORS w settings.py. Wartość domyślna obejmuje, między innymi, framework django messages.

W ten sposób definiujesz wiadomość, którą chcesz wyświetlić, używając na przykład messages.error i wyświetlasz wiadomość w szablonie przy użyciu zmiennej messages.

Innymi słowy, można napisać swój pogląd tak:

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()), 
      ) 

w szablonie 404.html, trzeba napisać coś takiego:

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

To trochę bardziej skomplikowane, ale ma tę zaletę, że możesz wysyłać kilka wiadomości, a nawet używać różnych rodzajów wiadomości (Ostrzeżenie, Debugowanie, Informacje, Błąd itp.). Możesz przeczytać więcej o strukturze komunikatów django tutaj: The messages framework | Django Documentation.

1

mam prostsze rozwiązanie

Wystarczy napisać middleware, że weźmie swój tekst błędu w jakiejś zmiennej żądania. Patrz przykład

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 

W 404.html

{{ request.error_404_message }} 
Powiązane problemy