Đ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 M2mô hình và các đối M1tượng tương đối của nó bằng cách sử dụng select_relationtrường và M3các đối tượng sử dụng prefetch_relationtrường.
Tuy nhiên, như chúng tôi đã đề cập đến M1mối quan hệ từ M2a 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 M3mối quan hệ từ đó M2là ManyToManyFieldcó 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, m22ngườ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 M3cá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,5ID 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 M2cá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 M2bảng và như bước cuối cùng, Django sẽ thực hiện truy vấn vào M3bả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 M2cá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.