פחות שאילתות
חלק מהיחידה מודלים וממשק הניהול במסלול ה-Django של Coddy. שיעור 19 מתוך 23.
דף הבית מדפיס את המחבר של כל ספר, ולכך יש מחיר: שאילתה אחת מביאה את הספרים, ואז {{ book.author.name }} מריץ שאילתה נוספת עבור כל ספר. עשרה ספרים, אחת־עשרה שאילתות; אלף ספרים, אלף ואחת. זו בעיית N+1, סיבה נפוצה לכך שדף Django איטי.
select_related() פותר זאת: ה־ORM מביא את הרשומה הקשורה באותה שאילתה, באמצעות JOIN ב־SQL. דף הלוואות שמדפיס את הכותרת של הספר עבור כל הלוואה ידרוש:
loans = Loan.objects.select_related("book")מעבירים לו את השם של שדה ה־ForeignKey, זה שקוראים באמצעות loan.book, והוא עדיין משתלב בשרשור עם filter() ועם order_by(). הוא עוקב רק אחר ForeignKeys קדימה; כדי לחזור לאחור ולגשת לשדות רבים־לרבים משתמשים ב־prefetch_related(), שנכיר בפרויקט Authors. לאחר מכן הדף נראה אותו הדבר, אבל מספר השאילתות קטן יותר.
אתגר
בינונידף הבית ודף החיפוש מציגים שניהם את המחבר של כל ספר. דאגו לכך שכל אחד מהם יביא את המחברים יחד עם הספרים, כדי שמספר השאילתות יישאר זהה ללא קשר למספר הספרים:
- תצוגת
home - תצוגת
search
לחצו על Run: הדפים נראים אותו הדבר. הבדיקות סופרות את השאילתות.
נסו בעצמכם
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})
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה מודלים וממשק הניהול
תרגלו בעצמכם: Django אונליין