paperwork: Use window functions for CertificationVersion is_current/is_latest

This should be a lot more efficient, and is much cleaner code too
This commit is contained in:
Adam Goldsmith 2023-12-01 13:05:27 -05:00
parent caf8c2cf45
commit a50112c534

View File

@ -4,7 +4,8 @@ from typing import TypedDict, TYPE_CHECKING, Optional
from semver import VersionInfo
from django.db import models
from django.db.models import OuterRef, Q, ExpressionWrapper, Subquery
from django.db.models import Q, Window
from django.db.models.functions import FirstValue
from django.conf import settings
from django.core.validators import RegexValidator
from django_stubs_ext import WithAnnotations
@ -139,18 +140,23 @@ class CertificationVersionAnnotations(TypedDict):
class CertificationVersionManager(models.Manager["CertificationVersion"]):
def get_queryset(self) -> models.QuerySet["CertificationVersion"]:
qs = super().get_queryset()
latest = qs.filter(definition__pk=OuterRef("definition__pk")).reverse()
return qs.annotate(
is_latest=ExpressionWrapper(
Q(pk=Subquery(latest.values("pk")[:1])),
output_field=models.BooleanField(),
),
# TODO: should do a more correct comparison than just major version
is_current=ExpressionWrapper(
Q(major=Subquery(latest.values("major")[:1])),
output_field=models.BooleanField(),
),
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)),
)
)