From bbd4d8d7003b80153d3486407f474491565bec1e Mon Sep 17 00:00:00 2001 From: Adam Goldsmith Date: Wed, 7 Feb 2024 21:27:30 -0500 Subject: [PATCH] paperwork: Fix CertificationVersion is_latest/is_current when filtered Unsurprisingly, filtering breaks window functions. Subqueries are less elegant, but actually work :) --- paperwork/models.py | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/paperwork/models.py b/paperwork/models.py index 0038b21..fbea35a 100644 --- a/paperwork/models.py +++ b/paperwork/models.py @@ -5,8 +5,7 @@ from typing import TYPE_CHECKING, TypedDict from django.conf import settings from django.core.validators import RegexValidator from django.db import models -from django.db.models import Q, Window -from django.db.models.functions import FirstValue +from django.db.models import OuterRef, Q, Subquery from django_stubs_ext import WithAnnotations from semver import VersionInfo @@ -142,23 +141,18 @@ class CertificationVersionAnnotations(TypedDict): class CertificationVersionManager(models.Manager["CertificationVersion"]): def get_queryset(self) -> models.QuerySet["CertificationVersion"]: - window = { - "partition_by": "definition", - "order_by": [ - "-major", - "-minor", - "-patch", - "-prerelease", - ], - } - return ( - super() - .get_queryset() - .annotate( - is_latest=Q(pk=Window(FirstValue("pk"), **window)), - # TODO: should do a more correct comparison than just major version - is_current=Q(major=Window(FirstValue("major"), **window)), - ) + qs = super().get_queryset() + department_versions = qs.filter(definition=OuterRef("definition")).order_by( + "-major", + "-minor", + "-patch", + "-prerelease", + ) + + return qs.annotate( + is_latest=Q(pk=Subquery(department_versions.values("pk")[:1])), + # TODO: should do a more correct comparison than just major version + is_current=Q(major=Subquery(department_versions.values("major")[:1])), )