python - 查询 Django 中所有类型的每个唯一类型的第 n 个最新条目
问题描述
我已经研究过这个问题,答案是关于获取每种类型的最新信息,例如这个主题。
不同之处在于我想为所有n
类型获取每种类型的最新项目。目前我得到所有项目,然后在 python 中找到第 n 个最近的条目,这非常慢。
例如
class CakeType(models.Model):
name = models.CharField(max_length=40)
class CakeEntry(models.Model):
cake_type = models.ForeignKey(CakeType, on_delete=models.CASCADE)
created = models.DateTimeField()
怎么会说CakeEntry
所有不同/独特的 5 个最新CakeType
的?
我将数据库从 MySQL 迁移到 PostgreSQL(做了大量工作),所以我可以使用 Postgres 的DISTINCT ON
.
阅读文档后,我尝试了以下操作:
from django.db.models import F, Window
from django.db.models.functions import Rank
cake_entries = (
CakeEntry.objects.order_by(
'-created'
).annotate(
rank=Window(
expression=Rank(),
partition_by=[F('cake_type_id')],
order_by=F('created').desc(),
),
).filter(rank__lt=5)
)
但是如果django.db.utils.NotSupportedError: Window is disallowed in the filter clause.
没有等级/分区,我不确定如何做到这一点。
解决方案
由于目标冲突,我看不到使用 Window 的方法:
为了解决过滤器问题,必须创建一个子查询。问题是用作表达式(注释)的子查询应该返回 1 行,以便将特定排名绑定到特定外部引用,但 Window 需要所有相关行的范围。最好的说明如下:
# Pk 21 has rank 3
CakeEntry.objects.all().annotate(rank=rank).values("rank", "pk")[:3]
Out[11]: <QuerySet [{'pk': 2, 'rank': 1}, {'pk': 1, 'rank': 2}, {'pk': 21, 'rank': 3}]>
# Due to filter, pk 21 has rank 1, even though you seemingly filter after the annotation
CakeEntry.objects.all().annotate(rank=rank).values("rank", "pk").filter(pk=21)
Out[12]: <QuerySet [{'pk': 21, 'rank': 1}]>
我能想到的最接近的是:
class CakeEntryManager(models.Manager):
def top5_per_type(self):
cake_types = CakeType.objects.all()
qs = self.get_queryset()
results = qs.none()
for ct in cake_types:
results = results.union(qs.filter(cake_type=ct).order_by("-created")[:5])
return results.order_by("cake_type", "-created")
推荐阅读
- machine-learning - 异常值的准确预测
- prestashop - 如何在 Prestashop 1.6 中手动延迟加载图像?
- php - 将其转换为准备好的语句
- c++ - 有没有办法让 Visual Studio 假定 #define 的值?
- ruby-on-rails - 使用 Ruby 和 MongoID 排序不排序
- kotlin - 检查字符串上的小写和大写
- animation - 如何从 2018 FBX SDK 中获取反向绑定姿势矩阵?
- ngxs - 如何从 NGXS 商店获取以前的状态
- php - 字符串到数组,由新行和括号分割
- javascript - 800ms 后删除下一个 div 的类