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

boa*_*der 5 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
Run Code Online (Sandbox Code Playgroud)

和这样的活动

class Activity(models.Model):
  when = models.DateTimeField()
  employee = models.ForeignKey(Employee, related_name='activity_set')
Run Code Online (Sandbox Code Playgroud)

我想使用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')
Run Code Online (Sandbox Code Playgroud)

请注意,在activity_set预取查询中,我无法切片到只能获得最新的条目,这是一个值得关注的内存消耗量.

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

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

alo*_*ser 0

我怀疑你没有抓住重点prefetch_related。文档指出这是预期的行为:许多查询和 python 中的“连接”。如果您想要更少的查询,您应该使用select_related另外,我不确定它是否适用于您的特定模型(问题中未说明),因为 select_lated 确实适用于多对多关系。

\n\n

更新-文档:

\n\n
\n

另一方面,prefetch_lated对每个关系进行单独的查找,并在 Python 中执行 \xe2\x80\x98joining\xe2\x80\x99

\n
\n