Menu
CoddyTech

Ít truy vấn hơn

Thuộc phần Model và trang quản trị trong hành trình Django của Coddy. Bài học 19 trên 23.

Trang chủ in tên tác giả của từng cuốn sách, việc này có cái giá của nó: một truy vấn lấy danh sách sách, sau đó {{ book.author.name }} chạy thêm một truy vấn cho mỗi cuốn sách. Mười cuốn sách, mười một truy vấn; một nghìn cuốn sách, một nghìn lẻ một truy vấn. Đây là vấn đề N+1, một lý do phổ biến khiến trang Django chạy chậm.

select_related() khắc phục vấn đề này: ORM lấy hàng liên quan trong cùng một truy vấn, bằng một SQL JOIN. Một trang hiển thị các khoản cho vay và in tiêu đề sách của từng khoản sẽ cần:

loans = Loan.objects.select_related("book")

Bạn truyền tên trường ForeignKey, trường mà bạn đọc bằng loan.book, và vẫn có thể nối thêm filter() và order_by(). Cách này chỉ đi theo ForeignKey theo chiều xuôi. Với sách của một tác giả và các trường nhiều-nhiều, bạn cần prefetch_related(), được dùng trong dự án Authors. Sau đó, trang trông vẫn như cũ nhưng dùng ít truy vấn hơn.

challenge icon

Thử thách

Trung bình

Trong books/views.py, hãy chỉnh sửa QuerySet trong home và search để lấy thông tin tác giả của mỗi cuốn sách bằng cùng một truy vấn. Giữ nguyên bộ lọc tìm kiếm.

Nhấn Chạy: các trang vẫn hiển thị như cũ. Các bài kiểm tra thêm mười cuốn sách và cho phép hai truy vấn trên mỗi trang.

Tự làm thử

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})
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Model và trang quản trị

Tự luyện tập: Playground Django