Meno query
Fa parte della sezione Modelli e pannello di amministrazione del percorso Django di Coddy. Lezione 19 di 23.
La pagina iniziale stampa l'autore di ogni libro, e questo ha un costo: una query recupera i libri, poi {{ book.author.name }} esegue un'altra query per ogni libro. Dieci libri, undici query; mille libri, mille e una. Questo è il problema N+1, un motivo comune per cui una pagina Django è lenta.
select_related() risolve il problema: l'ORM recupera la riga correlata nella stessa query, con una JOIN SQL. Una pagina di prestiti che stampa il titolo del libro di ogni prestito richiederebbe:
loans = Loan.objects.select_related("book")Gli passi il nome del campo ForeignKey, quello che leggi come loan.book, e continua a funzionare in catena con filter() e order_by(). Segue le ForeignKey solo in avanti. Per i libri di un autore e per i campi molti-a-molti ti serve prefetch_related(), usato nel progetto Authors. In seguito, la pagina ha lo stesso aspetto, ma con meno query.
Sfida
MedioIn books/views.py, fai in modo che le QuerySet in home e search recuperino l'autore di ciascun libro con la stessa query. Mantieni il filtro di ricerca.
Premi «Esegui»: le pagine sembrano uguali. I controlli aggiungono dieci libri e consentono due query per pagina.
Provalo tu
from django.shortcuts import get_object_or_404, render
from .models import Book
def home(request):
books = Book.objects.all()
return render(request, "books/home.html", {"books": books})
def book_detail(request, pk):
book = get_object_or_404(Book, pk=pk)
return render(request, "books/book_detail.html", {"book": book})
def search(request):
q = request.GET.get("q", "")
books = Book.objects.filter(title__icontains=q)
return render(request, "books/search.html", {"q": q, "books": books})
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Modelli e pannello di amministrazione
Esercitati da solo: Playground Django