47 lines
1.4 KiB
Python

from typing import TypeVar
from django.db.models import Avg, OuterRef, IntegerField, Value, Subquery
from django.db.models.functions import Coalesce
from django.db import models
T = TypeVar('T')
class PublicationQuerySet(models.QuerySet[T]):
def with_score(self):
qs = self
qs = qs.annotate(average_score=Coalesce(Avg("ratings__score"), 0.0))
return qs
def only_publish(self):
from .models import Publication
qs = self
return qs.filter(status=Publication.StatusVarioations.PUBLIC.value)
def with_user_score(self, user):
from .models import Rating
user_rating = Rating.objects.filter(
publication=OuterRef("pk"),
user=user
).values("score")[:1]
return self.annotate(
current_user_score=Coalesce(
Subquery(user_rating, output_field=IntegerField()),
Value(0)
)
)
class PublicationManager(models.Manager[T]):
def get_queryset(self):
return PublicationQuerySet[T](self.model, using=self._db).with_score()
def with_related(self):
return self.get_queryset().select_related('user', 'category')
def with_user_score(self, user):
return self.get_queryset().with_user_score(user)
def only_publish(self):
return self.get_queryset().only_publish()