00
:
00
:
00
:
00
•Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

Redirect e Errori HTTP

La gestione corretta dei redirect e degli errori HTTP è fondamentale per offrire una buona esperienza utente e per mantenere una navigazione coerente. Django fornisce strumenti integrati per gestire reindirizzamenti, errori 404, 500 e altre situazioni comuni.

Redirect con redirect()

La funzione redirect() è lo shortcut piu utilizzato per reindirizzare l’utente a un’altra pagina:

from django.shortcuts import redirect

def crea_articolo(request):
    if request.method == 'POST':
        # Salva l'articolo...
        articolo = Articolo.objects.create(
            titolo=request.POST['titolo'],
            contenuto=request.POST['contenuto'],
        )

        # Redirect usando il nome della URL
        return redirect('blog:dettaglio', slug=articolo.slug)

    return render(request, 'blog/crea.html')

redirect() accetta diversi tipi di argomento:

# Redirect a una URL con nome
return redirect('blog:lista')

# Redirect a un URL assoluto
return redirect('/blog/')

# Redirect a un URL esterno
return redirect('https://www.esempio.com')

# Redirect a un oggetto con get_absolute_url()
return redirect(articolo)

# Redirect permanente (301)
return redirect('blog:lista', permanent=True)

HttpResponseRedirect

Per un controllo piu fine, usa HttpResponseRedirect direttamente:

from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
from django.urls import reverse

def vecchia_pagina(request):
    # Redirect temporaneo (302)
    return HttpResponseRedirect(reverse('blog:lista'))

def url_cambiato(request):
    # Redirect permanente (301) - usato quando una URL cambia definitivamente
    return HttpResponsePermanentRedirect(reverse('nuova-pagina'))

La differenza tra redirect temporaneo (302) e permanente (301) e importante per la SEO: il redirect 301 indica ai motori di ricerca di aggiornare i propri indici.

Errore 404: Pagina Non Trovata

Sollevare Http404

Per indicare che una risorsa non esiste, solleva l’eccezione Http404:

from django.http import Http404

def dettaglio_articolo(request, slug):
    try:
        articolo = Articolo.objects.get(slug=slug)
    except Articolo.DoesNotExist:
        raise Http404("Articolo non trovato")

    return render(request, 'blog/dettaglio.html', {'articolo': articolo})

Lo Shortcut get_object_or_404()

get_object_or_404() semplifica il pattern sopra in una sola riga:

from django.shortcuts import get_object_or_404

def dettaglio_articolo(request, slug):
    articolo = get_object_or_404(Articolo, slug=slug)
    return render(request, 'blog/dettaglio.html', {'articolo': articolo})

Funziona anche con queryset filtrati:

# Con filtri aggiuntivi
articolo = get_object_or_404(Articolo, slug=slug, pubblicato=True)

# Con un queryset personalizzato
articoli_pubblicati = Articolo.objects.filter(pubblicato=True)
articolo = get_object_or_404(articoli_pubblicati, slug=slug)

Esiste anche get_list_or_404() per le liste:

from django.shortcuts import get_list_or_404

def per_categoria(request, categoria):
    articoli = get_list_or_404(Articolo, categoria__slug=categoria)
    return render(request, 'blog/lista.html', {'articoli': articoli})

Risposte di Errore HTTP

Django fornisce classi specifiche per i diversi codici di errore:

from django.http import (
    HttpResponseBadRequest,      # 400
    HttpResponseForbidden,       # 403
    HttpResponseNotFound,        # 404
    HttpResponseNotAllowed,      # 405
    HttpResponseServerError,     # 500
)

def vista_protetta(request):
    if not request.user.has_perm('blog.modifica'):
        return HttpResponseForbidden("Non hai i permessi per questa azione.")
    # Logica della view...

def solo_post(request):
    if request.method != 'POST':
        return HttpResponseNotAllowed(['POST'])
    # Elabora la richiesta POST...

Handler Personalizzati per gli Errori

Django permette di personalizzare le pagine di errore definendo handler nel file urls.py principale del progetto:

# miosito/urls.py
handler400 = 'miosito.views.errore_400'
handler403 = 'miosito.views.errore_403'
handler404 = 'miosito.views.errore_404'
handler500 = 'miosito.views.errore_500'
# miosito/views.py
from django.shortcuts import render

def errore_400(request, exception):
    return render(request, 'errori/400.html', status=400)

def errore_403(request, exception):
    return render(request, 'errori/403.html', status=403)

def errore_404(request, exception):
    return render(request, 'errori/404.html', status=404)

def errore_500(request):
    # Nota: handler500 non riceve il parametro exception
    return render(request, 'errori/500.html', status=500)

Le pagine di errore personalizzate sono visibili solo quando DEBUG = False. In modalita di sviluppo, Django mostra le sue pagine di debug dettagliate.

Template per le Pagine di Errore

Crea template dedicati nella cartella templates/errori/:

<!-- templates/errori/404.html -->
<!DOCTYPE html>
<html>
<head><title>Pagina non trovata</title></head>
<body>
    <h1>404 - Pagina non trovata</h1>
    <p>La pagina che stai cercando non esiste.</p>
    <a href="{% url 'home' %}">Torna alla home</a>
</body>
</html>

Conclusione

Django offre un sistema completo per gestire redirect e errori HTTP. Lo shortcut redirect() semplifica i reindirizzamenti, get_object_or_404() elimina codice ripetitivo per la gestione degli oggetti inesistenti, e gli handler personalizzati permettono di creare pagine di errore professionali e coerenti con il design del sito.