Collection: further improve stoken performance.
We merged the two queries into one and we made it like in the view, so we can now merge the two instead of having two implementations.
This commit is contained in:
parent
bb070639a3
commit
4ce96e043e
@ -17,7 +17,8 @@ from pathlib import Path
|
|||||||
from django.db import models, transaction
|
from django.db import models, transaction
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.validators import RegexValidator
|
from django.core.validators import RegexValidator
|
||||||
from django.db.models import Max
|
from django.db.models import Max, Value as V
|
||||||
|
from django.db.models.functions import Coalesce, Greatest
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.crypto import get_random_string
|
from django.utils.crypto import get_random_string
|
||||||
|
|
||||||
@ -39,6 +40,8 @@ class Collection(models.Model):
|
|||||||
main_item = models.OneToOneField("CollectionItem", related_name="parent", null=True, on_delete=models.SET_NULL)
|
main_item = models.OneToOneField("CollectionItem", related_name="parent", null=True, on_delete=models.SET_NULL)
|
||||||
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
|
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
stoken_id_fields = ["items__revisions__stoken", "members__stoken"]
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.uid
|
return self.uid
|
||||||
|
|
||||||
@ -56,9 +59,15 @@ class Collection(models.Model):
|
|||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def stoken(self):
|
def stoken(self):
|
||||||
stoken1 = self.items.aggregate(stoken=Max("revisions__stoken"))["stoken"] or 0
|
aggr_fields = [Coalesce(Max(field), V(0)) for field in self.stoken_id_fields]
|
||||||
stoken2 = self.members.aggregate(stoken=Max("stoken"))["stoken"] or 0
|
max_stoken = Greatest(*aggr_fields) if len(aggr_fields) > 1 else aggr_fields[0]
|
||||||
stoken_id = max(stoken1, stoken2)
|
stoken_id = (
|
||||||
|
self.__class__.objects.filter(main_item=self.main_item)
|
||||||
|
.annotate(max_stoken=max_stoken)
|
||||||
|
.values("max_stoken")
|
||||||
|
.first()["max_stoken"]
|
||||||
|
)
|
||||||
|
|
||||||
if stoken_id == 0:
|
if stoken_id == 0:
|
||||||
raise Exception("stoken is None. Should never happen")
|
raise Exception("stoken is None. Should never happen")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user