Wprowadzenie.
W 6 wpisie przedstawiłem w jaki sposób wywoływać własne szablony w przypadku wystąpienia kodu błędu, jednakże taka konstrukcja nie rozwiązuje nam wszystkich problemów. W 9 wpisie stworzyliśmy odwoływanie się do szczegółów poszczególnych filmów na podstawie numeru klucza podstawowego. Może zdarzyć się tak, że żądany klucz podstawowy nie będzie istniał, wówczas serwer zgłosi błąd 500 (wewnętrzny błąd serwera). Wystąpienie takiej sytuacji powinniśmy przewidzieć i odpowiednio na nią zareagować.
Zakres artykułu.
- Tworzenie aplikacji Django – Zwracanie szablonu dla błędu w przypadku nieistniejącego obiektu
Tworzenie aplikacji Django – Zwracanie szablonu dla błędu w przypadku nieistniejącego obiektu
Obsługa tego typu sytuacji odbywa się w pliku views.py.
Przypomnijmy sobie jak obecnie wyglądał plik views.py.
from django.http import HttpResponse from django.shortcuts import render from .models import WatchedMovies def error_404_my_view(request, exception): return render(request, 'myFirstApp/error404.html') def index(request): movies = WatchedMovies.objects.order_by('title') context = { 'movies': movies, } return render(request, 'myFirstApp/index.html', context) def myNextPage(request): return HttpResponse("<b>To jest moja następna strona!</b>") def detail(request, watchedMovies_id): movie = WatchedMovies.objects.get(pk=watchedMovies_id) context = { 'movie': movie, } return render(request, 'myFirstApp/detail.html', context)
Po wpisaniu ręcznie adresu URL z nieistniejącym kluczem podstawowym (na przykład 7) otrzymamy następujący efekt.
W celu przechwycenia tego wyjątku musimy zaimportować clasę Http404 z django.http, a następnie wykorzystać konstrukcję do przechwytywania wyjątków try except. Po pojawieniu się wyjątku należy wywołać klasę Http404, co spowoduje przekierowanie na wcześniej skonfigurowany, nasz szablon error404.html.
Modyfikacja pliku views.py wygląda następująco.
from django.http import HttpResponse, Http404 from django.shortcuts import render from .models import WatchedMovies def error_404_my_view(request, exception): return render(request, 'myFirstApp/error404.html') def index(request): movies = WatchedMovies.objects.order_by('title') context = { 'movies': movies, } return render(request, 'myFirstApp/index.html', context) def myNextPage(request): return HttpResponse("<b>To jest moja następna strona!</b>") def detail(request, watchedMovies_id): try: movie = WatchedMovies.objects.get(pk=watchedMovies_id) context = { 'movie': movie, } except WatchedMovies.DoesNotExist: raise Http404("Movie does not exist") return render(request, 'myFirstApp/detail.html', context)
Po ponownym wpisaniu adresu URL z nieistniejącym kluczem podstawowym (7) otrzymamy teraz następujący efekt.
Przechwycenie wyjątku możemy też zrealizować przy pomocy skrótków django.shortcuts importując metodę get_object_or_404. Taka konstrukcja nie zmienia nam działania aplikacji, a jedynie pomaga w zaoszczędzeniu czasu i miejsca przy pisaniu kodu.
Modyfikacja pliku views.py w takim przypadku wygląda następująco.
from django.http import HttpResponse from django.shortcuts import render, get_object_or_404 from .models import WatchedMovies def error_404_my_view(request, exception): return render(request, 'myFirstApp/error404.html') def index(request): movies = WatchedMovies.objects.order_by('title') context = { 'movies': movies, } return render(request, 'myFirstApp/index.html', context) def myNextPage(request): return HttpResponse("<b>To jest moja następna strona!</b>") def detail(request, watchedMovies_id): movie = get_object_or_404(WatchedMovies, pk=watchedMovies_id) context = { 'movie': movie, } return render(request, 'myFirstApp/detail.html', context)
Metoda get_object_or_404 zgłosi wyjątek w przypadku, gdy klucz podstawowy nie będzie istniał.
Natomiast odpowiedź po wpisaniu ręcznie adresu URL z nieistniejącym kluczem podstawowym (7), pozostaje niezmieniona.