在Django ORM中加入子查询

乔希

我想使用Django的ORM运行过滤器,以便每个用户的最新会话都能得到一组独特的用户。我已经建立了桌子,这样一个桌子user有很多sessions; 有一个UserSession模型,其中的Session模型有个user = models.ForeignKey(User)

到目前为止Users.objects.distinct('username').order_by('session__last_accessed')我已经尝试过了,但是我知道这是行不通的,因为Django将session.last_accessed列放入选择中,因此它返回了我,例如,5个重复的用户名和5个不同的会话,而不是最近的一个会话和用户。

是否可以通过Django的ORM进行查询?

编辑:好的,在使用SQL进行一些测试之后,我发现我要使用的SQL是:

select user.username, sub_query.last_accessed from (
  select user_id, max(last_accessed) as last_accessed
  from session
  group by user_id
) sub_query
join user on
user.id = sub_query.user_id
order by sub_query.last_accessed desc
limit 5

而且我可以sub_query通过Session.objects.values('user').annotate(last_accessed=Max('last_accessed'))我该如何使用sub_queryORM获得所需的数据?

编辑2:具体来说,我想仅通过执行一个查询来执行此操作,就像上面的SQL一样。当然,我可以查询两次并使用Python进行一些处理,但是我更喜欢在使用ORM时一次访问数据库。

鲁德拉

如果您使用的是mysql后端,则以下解决方案可能会有用:

users_in_session = Session.objects.values_list('user_id', flat=True)
sessions_by_the_user_list = Session.objects \
                            .filter(user__in=set(users_in_session)) \
                            .order_by('last_accessed').distinct()

如果使用sub_query,则order_by('last_accessed')函数应足以在有序列表中获取数据。尽管据我测试,这些结果似乎不稳定。

更新:

你可以试试:

Session.objects.values('user') \
  .annotate(last_accessed=Max('last_accessed')) \
  .orde‌​r_by('last_accessed').distinct()

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章