Đi qua các câu trả lời đã được đăng. Chỉ cần nghĩ rằng sẽ tốt hơn nếu tôi thêm một câu trả lời với ví dụ thực tế.
Giả sử bạn có 3 mẫu Django có liên quan.
class M1(models.Model):
name = models.CharField(max_length=10)
class M2(models.Model):
name = models.CharField(max_length=10)
select_relation = models.ForeignKey(M1, on_delete=models.CASCADE)
prefetch_relation = models.ManyToManyField(to='M3')
class M3(models.Model):
name = models.CharField(max_length=10)
Tại đây bạn có thể truy vấn M2
mô hình và các đối M1
tượng tương đối của nó bằng cách sử dụng select_relation
trường và M3
các đối tượng sử dụng prefetch_relation
trường.
Tuy nhiên, như chúng tôi đã đề cập đến M1
mối quan hệ từ M2
a ForeignKey
, nó chỉ trả về 1 bản ghi cho bất kỳ M2
đối tượng nào . Điều tương tự cũng áp dụng cho OneToOneField
.
Nhưng M3
mối quan hệ từ đó M2
là ManyToManyField
có thể trả về bất kỳ số lượng M1
đối tượng nào.
Hãy xem xét một trường hợp bạn có 2 M2
đối tượng m21
, m22
người có cùng 5 liên quan M3
đối tượng với ID 1,2,3,4,5
. Khi bạn tìm nạp M3
các đối tượng được liên kết cho từng M2
đối tượng đó, nếu bạn sử dụng chọn có liên quan, đây là cách nó sẽ hoạt động.
Các bước:
- Tìm
m21
đối tượng.
- Truy vấn tất cả các
M3
đối tượng liên quan đến m21
đối tượng có ID 1,2,3,4,5
.
- Lặp lại điều tương tự cho
m22
đối tượng và tất cả các M2
đối tượng khác .
Như chúng ta có cùng một 1,2,3,4,5
ID cho cả m21
, m22
đối tượng, nếu chúng tôi sử dụng tùy chọn select_related, nó sẽ truy vấn DB hai lần cho các ID cùng mà đã được lấy.
Thay vào đó, nếu bạn sử dụng prefetch_related, khi bạn cố gắng lấy M2
các đối tượng, nó sẽ ghi chú tất cả các ID mà các đối tượng của bạn trả về (Lưu ý: chỉ ID) trong khi truy vấn M2
bảng và như bước cuối cùng, Django sẽ thực hiện truy vấn vào M3
bảng với tập hợp tất cả các ID mà các M2
đối tượng của bạn đã trả về. và nối chúng với M2
các đối tượng bằng Python thay vì cơ sở dữ liệu.
Bằng cách này, bạn chỉ truy vấn tất cả các M3
đối tượng một lần để cải thiện hiệu suất.