gpt4 book ai didi

Django distinct相关查询

转载 作者:行者123 更新时间:2023-11-29 12:49:16 28 4
gpt4 key购买 nike

我有两个模型:

模型 A 是一个抽象用户模型和模型 B

class ModelB:
user = ForeignKey(User, related_name='modelsb')
timestamp = DateTimeField(auto_now_add=True)

我想知道有多少用户至少有一个在过去 7 天中至少 3 天创建了 ModelB 对象。

到目前为止,我已经找到了一种方法,但我确信有更好的方法,这就是我发布这个问题的原因。

我基本上将查询分为两部分。

第一部分:
我在用户模型中添加了一个 foo 方法,用于检查用户是否满足上述条件

def foo(self):
past_limit = starting_date - timedelta(days=7)
return self.modelsb.filter(timestamp__gte=past_limit).order_by('timestamp__day').distinct('timestamp__day').count() > 2

第 2 部分:
在自定义用户管理器中,我找到了在过去 7 天内拥有超过 2 个 modelsb 对象的用户,并为每个对象应用 foo 方法遍历它们。
通过这样做,我缩小了所需 for 循环的迭代次数。 (基本上它是一个过滤功能,但你明白了)

def boo(self):
past_limit = timezone.now() - timedelta(days=7)
candidates = super().get_queryset().annotate(rc=Count('modelsb', filter=Q(modelsb__timestamp__gte=past_limit))).filter(rc__gt=2)
return list(filter(lambda x: x.foo(), candidates))

但是,我想知道是否有更有效的方法来执行此操作,即没有 for 循环。

最佳答案

您可以使用条件注释。

我无法测试这个查询,但像这样的东西应该可以工作:

from django.db.models import Q, Count

past_limit = starting_date - timedelta(days=7)
users = User.objects.annotate(
modelsb_in_last_seven_days=Count('modelsb__timestap__day',
filter=Q(modelsb__timestamp__gte=past_limit),
distinct=True))
.filter(modelsb_in_last_seven_days__gte = 3)

编辑:

此解决方案无效,因为 distinct 选项确实指定了使条目不同的字段。

我在我自己的 Django 实例上做了一些试验,并找到了一种使用 SubQuery 来完成这项工作的方法。它的工作方式是我们生成一个子查询,我们自己进行区分。

counted_modelb = ModelB.objects
.filter(user=OuterRef('pk'), timestamp__gte=past_limit)
.values('timestamp__day')
.distinct()
.annotate(count=Count('timestamp__day'))
.values('count')

query = User.objects
.annotate(modelsb_in_last_seven_days=Subquery(counted_modelb, output_field=IntegerField()))
.filter(modelsb_in_last_seven_days__gt = 2)

这用用户的 modelb 中所有不同天数的计数来注释查询集中的每一行,日期大于所选日期。

在子查询中,我使用 values('timestamp__day') 来确保我可以执行 distinct()(因为 distinct('timestamp__day' )annotate() 不受支持。)

关于Django distinct相关查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58114374/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com