استعلامات أقل
جزء من قسم النماذج ولوحة الإدارة في رحلة 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(). وهي تتبع مفاتيح ForeignKey إلى الأمام فقط؛ أما الاتجاه العكسي والحقول متعددة إلى متعددة فتستخدم prefetch_related()، الذي تعرّفت إليه في مشروع Authors. ستبدو الصفحة كما هي بعد ذلك، لكن بعدد أقل من الاستعلامات.
التحدي
متوسطتعرض كلٌّ من الصفحة الرئيسية وصفحة البحث مؤلف كل كتاب. اجعل كلًّا منهما يجلب المؤلفين مع الكتب، بحيث يظل عدد الاستعلامات كما هو مهما بلغ عدد الكتب:
- العرض
home - العرض
search
اضغط على تشغيل: ستبدو الصفحات كما هي. تتحقق الاختبارات من عدد الاستعلامات.
جرّب بنفسك
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})
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس النماذج ولوحة الإدارة
تدرّب بنفسك: Playground لـ Django