使用django prefetch_related()来获取上次活动的时间

时间:2014-06-22 20:34:50

标签: django

我升级到了Django 1.7,所以我可以得到Prefetch objects,但是我很难让它们按预期运行。

我有一个像这样的员工模型:

class Employee(Human):
  ... additional Employee Fields ...

  def get_last_activity_date(self):
    try:
        return self.activity_set.all().order_by('-when')[0:1].get().when
    except Activity.DoesNotExist:
        return None

和这样的活动

class Activity(models.Model):
  when = models.DateTimeField()
  employee = models.ForeignKey(Employee, related_name='activity_set')

我想使用prefetch_related来获取此员工的上一个活动日期。我试图表达这么多方法,但无论我怎么做,最终都会产生另一个查询。我的另外2个prefetch_related部分按预期工作,但是这个部分似乎永远不会保存我任何查询。

我在Django Rest Framework中使用它,所以我真的需要prefetch_related部分才能工作,因为我无法到达DRF内部以进行查询集之外的映射。

以下是不工作

的方式之一
def get_queryset(self):

    return super(EmployeeViewSet, self).get_queryset()\
           .prefetch_related('phone_number_set', 'email_address_set')\
           .prefetch_related(Prefetch('activity_set', Activity.objects.all().order_by('-when')))\
           .order_by('last_name', 'first_name')

请注意,在activity_set预取查询中,我无法进行切片,只能获取最新的条目,这对于将要消耗多少内存感到担忧。

我确实看到预取查询发生了,但是然后每个员工都获得了对该信息的单独查询,这意味着我有一个更大的浪费查询,仍然得到我要阻止的~200个查询。

在这种情况下,如何让prefetch_related为我工作?

1 个答案:

答案 0 :(得分:0)

我怀疑你错过了prefetch_related的观点。这是预期行为的文档state:许多查询和“加入”#39;在python中。如果你想要更少的查询,你应该使用select_related而且我不确定它是否适用于你的特定模型(问题中未说明),因为select_related确实适用于多对多的关系。

更新 - 文档:

  另一方面,

prefetch_related,为每个关系执行单独的查找,并在Python中执行“加入”