diff --git a/api/v1/serializers/contest.py b/api/v1/serializers/contest.py index 6288c5fc..930f60f3 100644 --- a/api/v1/serializers/contest.py +++ b/api/v1/serializers/contest.py @@ -43,11 +43,20 @@ class ContestCreateSerializer(DispatchContentMixin, serializers.ModelSerializer) class ContestWorkSerializer(serializers.ModelSerializer): image = ImageObjectSerializer() + likes = serializers.SerializerMethodField() + user_liked = serializers.SerializerMethodField() class Meta: model = ContestWork fields = ['id', 'user', 'contest', 'image', 'child_full_name', 'age', - 'created_at', 'likes', 'img_width', 'img_height'] + 'created_at', 'likes', 'user_liked', 'img_width', 'img_height'] + + def get_likes(self, instance): + return instance.likes.count() + + def get_user_liked(self, instance): + user = self.context['request'].user + return instance.likes.filter(user=user).exists() if user.is_authenticated else False class ContestWorkCreateSerializer(serializers.ModelSerializer): @@ -55,5 +64,7 @@ class ContestWorkCreateSerializer(serializers.ModelSerializer): model = ContestWork fields = '__all__' + # TODO check ContestWork.objects.filter(user=self.request.user).exists() + def to_representation(self, instance): return ContestWorkSerializer(instance=instance, context=self.context).to_representation(instance) diff --git a/api/v1/serializers/course.py b/api/v1/serializers/course.py index bdb1a289..88533c51 100644 --- a/api/v1/serializers/course.py +++ b/api/v1/serializers/course.py @@ -15,7 +15,7 @@ from .content import ( from apps.content.models import ( Content, Image, Text, ImageText, Video, Gallery, GalleryImage, ImageObject, -) + ContestWork) from .user import UserSerializer from .mixins import DispatchContentMixin, DispatchGalleryMixin, DispatchMaterialMixin @@ -63,6 +63,34 @@ class LikeSerializer(serializers.ModelSerializer): ) +class LikeCreateSerializer(serializers.ModelSerializer): + OBJ_TYPE_CONTEST_WORK = 'contest_work' + + obj_type = serializers.CharField(required=True) + obj_id = serializers.IntegerField(required=True) + + class Meta: + model = Like + fields = ['obj_type', 'obj_id'] + + def create(self, validated_data): + user = self.context['request'].user + if not (user and user.is_authenticated): + return Like() + obj_type = validated_data.pop('obj_type') + obj_id = validated_data.pop('obj_id') + if obj_type == self.OBJ_TYPE_CONTEST_WORK: + contest_work = ContestWork.objects.get(pk=obj_id) + if contest_work.likes.filter(user=user).exists(): + return Like() + like = Like.objects.create(user=user) + contest_work.likes.add(like) + return like + + def to_representation(self, instance): + return LikeSerializer(instance, context=self.context).to_representation(instance) + + class CategorySerializer(serializers.ModelSerializer): class Meta: diff --git a/api/v1/views.py b/api/v1/views.py index 95fea15b..fd7567e6 100644 --- a/api/v1/views.py +++ b/api/v1/views.py @@ -14,7 +14,7 @@ from .serializers.course import ( CommentSerializer, MaterialSerializer, MaterialCreateSerializer, LessonSerializer, LessonCreateSerializer, -) + LikeCreateSerializer) from .serializers.content import ( BanerSerializer, ImageSerializer, ImageCreateSerializer, @@ -130,7 +130,11 @@ class MaterialViewSet(ExtendedModelViewSet): class LikeViewSet(ExtendedModelViewSet): queryset = Like.objects.select_related('user').all() - serializer_class = LikeSerializer + serializer_class = LikeCreateSerializer + serializer_class_map = { + 'list': LikeSerializer, + 'retrieve': LikeSerializer, + } search_fields = ('user__email', 'user__firstname', 'user__lastname',) ordering_fields = ('created_at', 'update_at',) # permission_classes = (IsAdmin,) @@ -448,7 +452,7 @@ class ContestViewSet(ExtendedModelViewSet): class ContestWorkViewSet(ExtendedModelViewSet): - queryset = ContestWork.objects.order_by('-created_at') + queryset = ContestWork.objects.all() serializer_class = ContestWorkCreateSerializer serializer_class_map = { 'list': ContestWorkSerializer, diff --git a/apps/content/models.py b/apps/content/models.py index 378c9995..bbf023d8 100644 --- a/apps/content/models.py +++ b/apps/content/models.py @@ -1,6 +1,7 @@ from urllib.parse import urlparse from django.db import models from django.contrib.auth import get_user_model +from django.urls import reverse_lazy from polymorphic.models import PolymorphicModel @@ -180,6 +181,11 @@ class ContestWork(models.Model): created_at = models.DateTimeField(auto_now_add=True) likes = models.ManyToManyField('course.Like', blank=True) + class Meta: + verbose_name = 'Конкурсная работа' + verbose_name_plural = 'Конкурсные работы' + ordering = ('-created_at',) + @property def img_width(self): return self.image.image.width if self.image and self.image.image else None @@ -187,3 +193,6 @@ class ContestWork(models.Model): @property def img_height(self): return self.image.image.height if self.image and self.image.image else None + + def get_absolute_url(self): + return reverse_lazy('contest_work', args=[self.id]) diff --git a/apps/content/templates/content/contest.html b/apps/content/templates/content/contest.html index 0c3c89a6..4c8a9f2f 100644 --- a/apps/content/templates/content/contest.html +++ b/apps/content/templates/content/contest.html @@ -12,7 +12,9 @@ {{ contest.description }}