47 lines
1.4 KiB
Python
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() |