假设以下型号
Class A(): pass
Class B():
i = integer()
aa = foreignkey('A', related_name = 'fka')
为简单起见,请假设以下条目
A() - a1 -> pk = 1
B() - b1 -> i = 1, aa = a1
B() - b2 -> i = 2, aa = a1
B() - b3 -> i = 3, aa = a1
B() - b4 -> i = 4, aa = a1
B() - b5 -> i = 5, aa = a1
我知道,
foo = A.objects.get(pk = 1).prefetch_related('fka')
会给我条目b1,b2,b3,b4和b5。
但我想知道的是,是否有可能以任何方式改变此查询以仅获得与A()相关联的B()的特定条目。 假设我想只预取' B'的输入,用' i'为2(得到b2,并跳过b1,b3,b4和b5)。
如果使用预取无法做到这一点,那么最好的方法是什么?
注意:get(pk = 1)
用于保持解释的简单性,但在那个位置通常会有filter(**conditions)
。
答案 0 :(得分:3)
是否有必要对A对象而不是B对象进行查询?如果您反向执行其他查找操作,则可以使用select_related()
:
foo = B.objects.select_related('aa').get(i=2)
这样可以减少数据库命中次数。因为prefetch_related()
总是进行自己的数据库查找,所以使用prefetch_related()的建议方案并不像编写的那样更有效:
a = A.objects.get(pk=1)
b = a.fka.get(i=2)
这并不是说在更复杂的过滤方案中它不会更有效,但select_related()
使用SQL连接,因此只能访问数据库一次。也就是说,如果你绝对必须首先查找A对象,最好的答案是:升级到Django 1.7。 Django 1.7中的新Prefetch
命令允许您指定自定义查询集,允许在prefetch_related()
上进行更复杂的操作,包括过滤:
qs = B.objects.filter(i=2)
foo = A.objects.get(pk = 1).prefetch_related(Prefetch('fka',qs))