【问题标题】:Simplifying Django Query Annotation简化 Django 查询注解
【发布时间】:2021-10-28 02:13:13
【问题描述】:

我有 3 个模型,一个函数被多次调用,但它会生成 200-300 个 sql 查询,我想减少这个数字。

我有以下布局:

class Info(models.Model):
    user = models.ForeignKey(User)
    ...

class Forum(models.Model):
    info = models.ForeignKey(Info)
    datum = models.DateTimeField()
    ...

class InfoViewed(models.Model):
    user = models.ForeignKey(User)
    infokom = models.ForeignKey(Info)
    last_seen = models.DateTimeField()
    ...

。我需要获取所有新论坛消息的数量,所以只有一个数字。目前它的工作原理是,我遍历所有相关的 Infokoms,并总结所有具有比相关 InfoViewed 的 last_seen 字段更高的数据的论坛。

这可行,但是会产生约 200 次查询 100 条信息。

有没有可能在几个查询中获取相同的数字?我尝试使用 annonate 和 django.db.models.Count,但失败了。

Django:1.11.16


目前我正在使用这个:

infos = Info.objects.filter(user_id=**x**)
return sum(i.number_of_new_forums(self.user) \
            for i in infos)

number_of_new_forums 看起来像这样:

info_viewed = self.info_viewed_set.filter(user=user)
return len([f.id for f in self.get_forums().\
            filter(datum__gt = info_viewed[0].last_seen)])

【问题讨论】:

  • 请添加您正在使用的查询
  • 嗯,这不是一个查询,但我更新了原始问题。
  • 该方法有什么作用get_forums()。为什么你总是取零索引项? info_viewed[0]
  • get_forums() 没有参数返回 forum_set.all() 并且零索引项目的原因是错误继承的代码。每个 (User, Info) 对应始终有一个 Info_viewed 元素。
  • 那么,开始创建此查询的正确方向是什么?显然我没有足够的 django ORM 知识来知道从哪个开始。

标签: django django-models django-queryset


【解决方案1】:

我设法从不同的角度想出了一些解决方案:

Forum.objects.filter(info_id__in=info_ids,
        info__info_viewed__user=request.user,
        datum__gt=F('info__info_viewed__last_seen')).count()

其中 info_ids 是所有相关信息的 id(列表),但是我不确定它是否是 100% procent 解决方案...。

如果有人可能有不同的方法,我会欢迎它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-25
    • 1970-01-01
    • 2022-09-23
    • 2013-08-28
    • 1970-01-01
    • 2018-02-16
    • 2022-01-08
    相关资源
    最近更新 更多