score on publications
This commit is contained in:
parent
d5cab4a322
commit
d10ad28310
@ -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]):
|
||||||
@ -16,6 +17,22 @@ class PublicationQuerySet(models.QuerySet[T]):
|
|||||||
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):
|
||||||
return PublicationQuerySet[T](self.model, using=self._db).with_score()
|
return PublicationQuerySet[T](self.model, using=self._db).with_score()
|
||||||
@ -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()
|
||||||
@ -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):
|
||||||
|
|||||||
@ -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'],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user