我想優化一些Django代碼,並且我有兩種類似的方法表現不同。下面是一些例子型號:Django過濾與預過濾對象的python過濾
class A(models.Model):
name = models.CharField(max_length=100)
class B(models.Model):
name = models.CharField(max_length=100)
a = models.ForeignKey(A)
c = models.ForeignKey(C)
class C(models.Model):
name = models.CharField(max_length=100)
對於每個A
對象,我想遍歷其傳入B
的一個子集,過濾,在他們的c
值。很簡單:
for a in A.objects.all() :
for b in a.B_set.filter(c__name='some_val') :
print a.name, b.name, c.name
這樣做的問題是,有用於遍歷每個a
值一個新的數據庫查找。
看來,解決方案是預取的c值將進入過濾器。
qs_A = A.objects.all().prefetch_related('B_set__c')
現在考慮下面的兩個過濾方法:
# Django filter
for a in qs_A :
for b in a.B_set.filter(c__name='some_val') :
print a.name, b.name, n.name
# Python filter
for a in qs_A :
for b in filter(lambda b: b.c.name == 'some_val', a.B_set.all()):
print a.name, b.name, c.name
由於我使用的數據,Django的過濾器,使比Python的過濾器48多個SQL查詢(在12元qs_A
結果組)。這讓我相信,Django過濾器不會使用預取表。
有人可以解釋發生了什麼?
也許有可能在預取過程中應用過濾器?