使用prefetch_related只获取关系的特定条目

时间:2014-09-09 23:51:21

标签: django django-models

假设以下型号

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)

1 个答案:

答案 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))