gpt4 book ai didi

python - Django 过滤、分页和注释分页结果

转载 作者:行者123 更新时间:2023-11-28 18:47:23 25 4
gpt4 key购买 nike

我有对象 Reports 和 ReportSubscriber,我想计算一份报告的订阅者数量。

一种解决方案是注释。我有很多报告,所以对所有报告进行注释需要大约 6 秒,所以我想也许最好在分页后进行注释:

filter_search = ReportFilter(request.GET, queryset=Report.objects.filter(
created_at__gt=start_date,
created_at__lte=end_date,
is_confirmed__exact=True,
).annotate(sub_count=Count("reportsubscriber")).order_by('-sub_count'))

paginator = Paginator(filter_search, 20)

result = paginator.page(1).object_list.annotate(
sub_count=Count("reportsubscriber"))

它有效,但它花费了相同的时间,当我检查查询时,它实际上仍然遍历了 report_subscriber 表中的所有行。所以我尝试使用 .extra()

filter_search = ReportFilter(request.GET, queryset=Report.objects.filter(
created_at__gt=start_date,
created_at__lte=end_date,
is_confirmed__exact=True,
))

paginator = Paginator(filter_search, 20)
paged_reports = paginator.page(1)

result = filter_search.qs.extra(
select={
'sub_count': 'SELECT COUNT(*) FROM reports LEFT OUTER JOIN report_subscribers \
ON (reports.id = report_subscribers.id) \
WHERE reports.id = report_subscribers.id \
AND report_subscribers.report_id IN %s \
' % "(%s)" % ",".join([str(r.id) for r in paged_reports.object_list])
},
order_by=['sub_count']
)

但是还是不行。我为所有报告获得了一个固定数量的订阅者。我错过了什么,也许有更好的方法来实现这一目标?谢谢

最佳答案

我不能给你一个明确的答案,我相信你的问题是即使分页,你的整个查询也必须执行,以便分页器知道有多少页。我认为你最好在分页之前去掉注释:

filter_search = ReportFilter(request.GET, queryset=Report.objects.filter(
created_at__gt=start_date,
created_at__lte=end_date,
is_confirmed__exact=True,
).order_by('-sub_count'))

paginator = Paginator(filter_search, 20)

result = paginator.page(1).object_list.annotate(
sub_count=Count("reportsubscriber"))

我从你的例子中相信 object_list 是一个你可以注释的查询集,但如果它只是一个对象的 list,你可以用类似的东西注释每一页结果:

pageIds = [report.id for report in paginator.page(1).object_list]
result = Report.objects.filter(id__in=pageIds).annotate(
sub_count=Count("reportsubscriber"))

但这都是在黑暗中拍摄的。你所做的一切看起来都太疯狂了,所以除非你的数据集很大,否则我只能想象你的问题是一个糟糕的索引查询。您真的会想要分析正在生成的实际查询。您可以通过从项目 Django shell 中针对给定的 start_dateend_data 执行来获取 SQL:

Report.objects.filter(
created_at__gt=start_date,
created_at__lte=end_date,
is_confirmed__exact=True,
).order_by('-sub_count').query

然后使用 EXPLAIN 在您的数据库上从 PSQL 命令行运行相同的查询.您需要阅读一些内容才能弄清楚如何解释结果。

关于python - Django 过滤、分页和注释分页结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17983820/

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