我有一个跟踪广告展示次数的模型。
class Impression(models.Model):
ad = models.ForeignKey(Ad, on_delete=models.CASCADE)
user_ip = models.CharField(max_length=50, null=True, blank=True)
clicked = models.BooleanField(default=False)
time_created = models.DateTimeField(auto_now_add=True)
我想找到展示次数超过1000次的所有user_ip
。换句话说,如果user_ip
出现在Impression
的1000多个实例中。我怎样才能做到这一点?我为此编写了一个函数,但效率非常低且速度慢,因为它会遍历每一次印象。
def check_ip():
for i in Impression.objects.all():
if Impression.objects.filter(user_ip=i.user_ip).count() > 1000:
print(i.user_ip)
答案 0 :(得分:2)
您应该能够在一个带聚合的查询中执行此操作..可以按以下方式过滤聚合值(如Count()
):
from django.db.models import Count
for ip in Impression.objects.values('user_ip').annotate(ipcount=Count('user_ip')).filter(ipcount__gt=1000):
# do something
答案 1 :(得分:0)
Django查询集有一个annotate()
方法,支持您尝试做的事情。
from django.db.models import Count
Impression.objects.values('user_ip')\
.annotate(ip_count=Count('user_ip'))\
.filter(ip_count__gt=1000)
这将为您提供一个查询集,该查询集返回带有“user_ip”的字典。和' ip_count'用作可迭代的键。
要了解此处发生的事情,您应该查看Django的汇总指南:https://docs.djangoproject.com/en/1.11/topics/db/aggregation/(特别是this section,它解释了annotate
如何与{{1}进行互动}})
生成的SQL类似于:
values