score on publications

This commit is contained in:
stepan323446 2026-01-16 12:47:44 +01:00
parent d5cab4a322
commit d10ad28310
3 changed files with 38 additions and 3 deletions

View File

@ -1,8 +1,9 @@
from typing import TypeVar
from django.db.models import Avg
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]):
@ -16,6 +17,22 @@ class PublicationQuerySet(models.QuerySet[T]):
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()
@ -23,5 +40,8 @@ class PublicationManager(models.Manager[T]):
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()

View File

@ -14,6 +14,7 @@ class PublicationSerializer(serializers.ModelSerializer):
category_detail = CategorySerializer(source="category", read_only=True)
user_detail = PublicUserSerializer(source="user", read_only=True)
average_score = serializers.SerializerMethodField(read_only=True)
current_user_score = serializers.IntegerField(default=0)
@extend_schema_field(serializers.FloatField())
def get_average_score(self, obj):
@ -51,9 +52,9 @@ class PublicationSerializer(serializers.ModelSerializer):
class Meta:
model = Publication
fields = ('pk', 'image', 'video', 'content_type', 'status', 'average_score', 'description', 'is_pinned', 'user', 'user_detail', 'category', 'category_detail','time_created', 'time_updated')
fields = ('pk', 'image', 'video', 'content_type', 'status', 'average_score', 'current_user_score', 'description', 'is_pinned', 'user', 'user_detail', 'category', 'category_detail','time_created', 'time_updated')
read_only_fields = ('time_created', 'time_updated', 'is_pinned', 'user', 'status')
read_only_fields = ('time_created', 'time_updated', 'is_pinned', 'user', 'status', 'current_user_score')
class AdminPublicationSerializer(PublicationSerializer):
class Meta(PublicationSerializer.Meta):

View File

@ -34,6 +34,13 @@ class PublicationsAPIView(ListCreateAPIView):
ordering = ['-time_created']
search_fields = ['user__username', 'description']
def get_queryset(self):
user: User = self.request.user
if user.is_authenticated:
return super().get_queryset().with_user_score(user)
return super().get_queryset()
def get_permissions(self):
if self.request.method == 'POST':
return [IsAuthenticated()]
@ -51,6 +58,13 @@ class PublicationDetailAPIView(RetrieveAPIView):
queryset = Publication.objects.with_related().only_publish()
serializer_class = PublicationSerializer
def get_queryset(self):
user: User = self.request.user
if user.is_authenticated:
return super().get_queryset().with_user_score(user)
return super().get_queryset()
@extend_schema(
tags=['Publications'],
methods=['GET'],