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 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.models.functions import Coalesce
from django.db import models from django.db import models
T = TypeVar('T') T = TypeVar('T')
class PublicationQuerySet(models.QuerySet[T]): class PublicationQuerySet(models.QuerySet[T]):
@ -15,6 +16,22 @@ class PublicationQuerySet(models.QuerySet[T]):
from .models import Publication from .models import Publication
qs = self qs = self
return qs.filter(status=Publication.StatusVarioations.PUBLIC.value) 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]): class PublicationManager(models.Manager[T]):
def get_queryset(self): def get_queryset(self):
@ -23,5 +40,8 @@ class PublicationManager(models.Manager[T]):
def with_related(self): def with_related(self):
return self.get_queryset().select_related('user', 'category') 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): def only_publish(self):
return self.get_queryset().only_publish() return self.get_queryset().only_publish()

View File

@ -14,6 +14,7 @@ class PublicationSerializer(serializers.ModelSerializer):
category_detail = CategorySerializer(source="category", read_only=True) category_detail = CategorySerializer(source="category", read_only=True)
user_detail = PublicUserSerializer(source="user", read_only=True) user_detail = PublicUserSerializer(source="user", read_only=True)
average_score = serializers.SerializerMethodField(read_only=True) average_score = serializers.SerializerMethodField(read_only=True)
current_user_score = serializers.IntegerField(default=0)
@extend_schema_field(serializers.FloatField()) @extend_schema_field(serializers.FloatField())
def get_average_score(self, obj): def get_average_score(self, obj):
@ -51,9 +52,9 @@ class PublicationSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Publication 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 AdminPublicationSerializer(PublicationSerializer):
class Meta(PublicationSerializer.Meta): class Meta(PublicationSerializer.Meta):

View File

@ -34,6 +34,13 @@ class PublicationsAPIView(ListCreateAPIView):
ordering = ['-time_created'] ordering = ['-time_created']
search_fields = ['user__username', 'description'] 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): def get_permissions(self):
if self.request.method == 'POST': if self.request.method == 'POST':
return [IsAuthenticated()] return [IsAuthenticated()]
@ -51,6 +58,13 @@ class PublicationDetailAPIView(RetrieveAPIView):
queryset = Publication.objects.with_related().only_publish() queryset = Publication.objects.with_related().only_publish()
serializer_class = PublicationSerializer 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( @extend_schema(
tags=['Publications'], tags=['Publications'],
methods=['GET'], methods=['GET'],