This answer là chính xác với các phiên bản của Django trước 1.7. Nó tạo ra ba truy vấn: đầu tiên, lấy cá thể của A
, sau đó lấy các cá thể có liên quan của nó là B
và cuối cùng tìm nạp các cá thể của C
liên quan đến trường hợp của B
được tìm nạp trong truy vấn thứ hai.
Trước Django 1,7, điều này là tốt nhất bạn có thể làm, thậm chí khi truy vấn thứ hai có thể, về mặt lý thuyết, chọn tất cả B
đối tượng cùng với C
đối tượng có liên quan tham gia thông qua các z
ForeignKey
.
Bắt đầu với Django 1.7, có lớp nâng cao hơn django.db.models.Prefetch
cho phép bạn thực hiện điều đó. Với Prefetch
bạn có thể tùy chỉnh queryset sử dụng để prefetch đối tượng liên quan như thế này:
foo = A.objects.prefetch_related(
Prefetch('a', queryset=B.objects.select_related('z'))
).get(pk=1)
Điều này dẫn đến chỉ có hai câu hỏi (như trái ngược với ba khi sử dụng prefetch_related('a__z')
) và cho phép các cơ sở dữ liệu chăm sóc thứ hai tham gia, mà nên về mặt lý thuyết, kết quả hoạt động tốt hơn một chút.
Đây là tất cả được bao gồm trong hướng dẫn sử dụng ... https://docs.djangoproject.com/en/dev/ref/models/querysets/, nhưng "có" là câu trả lời. – demux
Thực ra, câu trả lời là “không”, lệnh gọi 'select_related' được viết trong câu hỏi sẽ không hoạt động. Tôi sẽ thêm một câu trả lời mới. Nhân tiện, lệnh gọi 'get' phải ở cuối, không phải trước' select_related' và 'prefetch_related'. – koniiiik