diff --git a/docker/dev/env/.env b/docker/dev/env/.env index 433ee9d..d2326f3 100644 --- a/docker/dev/env/.env +++ b/docker/dev/env/.env @@ -7,7 +7,7 @@ CELERY_BROKER_URL=${REDIS_URL}/2 CELERY_RESULT_BACKEND=${REDIS_URL}/2 HEALTH_CHECK_URL=/application/health/ -ENABLE_SILK=0 +ENABLE_SILK=1 ENABLE_DEBUG_TOOLBAR=0 ENABLE_SENTRY=0 FRONTEND_URL=http://192.168.59.111:8008 diff --git a/docker/dev/web/Dockerfile b/docker/dev/web/Dockerfile index 52ecd1e..eee1fa0 100644 --- a/docker/dev/web/Dockerfile +++ b/docker/dev/web/Dockerfile @@ -14,7 +14,7 @@ ARG GID=1000 ARG UID=1000 ARG USER=ubuntu -RUN apk add --update --no-cache curl postgresql-dev gcc python3-dev musl-dev openssl libffi-dev openssl-dev build-base \ +RUN apk add --update --no-cache curl postgresql postgresql-dev gcc python3-dev musl-dev openssl libffi-dev openssl-dev build-base \ # install Pillow dependencies jpeg-dev zlib-dev freetype-dev lcms2-dev openjpeg-dev tiff-dev tk-dev tcl-dev harfbuzz-dev fribidi-dev && \ pip install --upgrade pip setuptools && \ diff --git a/web/api/v1/blog/serializers.py b/web/api/v1/blog/serializers.py index 729ab25..269f4bd 100644 --- a/web/api/v1/blog/serializers.py +++ b/web/api/v1/blog/serializers.py @@ -63,10 +63,6 @@ class Meta: class FullArticleSerializer(ArticleSerializer): votes = LikeDislikeRelationSerializer(many=True) - def get_parent_comment(self, obj): - queryset = obj.comment_set.filter(parent_id__isnull=True) - return CommentSerializer(queryset, source='comment_set', many=True).data - class Meta(ArticleSerializer.Meta): fields = ArticleSerializer.Meta.fields + ('votes',) @@ -90,35 +86,40 @@ def validate_title(self, title: str): class ParentCommentSerializer(serializers.ModelSerializer): - user = ShortUserSerializer() - like_status = serializers.SerializerMethodField(method_name='get_like_status') + user = ShortUserSerializer(read_only=True) + # like_status = serializers.SerializerMethodField(method_name='get_like_status') - def get_like_status(self, obj) -> LikeIconStatus: - user = self.context['request'].user - if not user.is_authenticated: - return LikeIconStatus.EMPTY - if like_obj := obj.votes.filter(user=user).first(): - return LikeIconStatus.LIKED if like_obj.vote == LikeStatus.LIKE else LikeIconStatus.DISLIKED - return LikeIconStatus.EMPTY + # def get_like_status(self, obj) -> LikeIconStatus: + # user = self.context['request'].user + # if not user.is_authenticated: + # return LikeIconStatus.EMPTY + # if like_obj := obj.votes.filter(user=user).first(): + # return LikeIconStatus.LIKED if like_obj.vote == LikeStatus.LIKE else LikeIconStatus.DISLIKED + # return LikeIconStatus.EMPTY class Meta: model = Comment - fields = ('id', 'content', 'updated', 'article', 'user', 'like_status') + fields = ( + 'id', + 'content', + 'updated', + 'article', + 'user', + ) -class CommentSerializer(serializers.ModelSerializer): - child = ParentCommentSerializer(many=True, read_only=True, source='parent_set') - parent_id = serializers.IntegerField(min_value=1, default=None) +class CommentListSerializer(serializers.ModelSerializer): + children = ParentCommentSerializer(many=True, read_only=True, source='parent_set') user = ShortUserSerializer(read_only=True) - like_status = serializers.SerializerMethodField(method_name='get_like_status') - - def get_like_status(self, obj) -> LikeIconStatus: - user = self.context['request'].user - if not user.is_authenticated: - return LikeIconStatus.EMPTY - if like_obj := obj.votes.filter(user=user).first(): - return LikeIconStatus.LIKED if like_obj.vote == LikeStatus.LIKE else LikeIconStatus.DISLIKED - return LikeIconStatus.EMPTY + # like_status = serializers.SerializerMethodField(method_name='get_like_status') + # + # def get_like_status(self, obj) -> LikeIconStatus: + # user = self.context['request'].user + # if not user.is_authenticated: + # return LikeIconStatus.EMPTY + # if like_obj := obj.votes.filter(user=user).first(): + # return LikeIconStatus.LIKED if like_obj.vote == LikeStatus.LIKE else LikeIconStatus.DISLIKED + # return LikeIconStatus.EMPTY class Meta: model = Comment @@ -126,11 +127,10 @@ class Meta: 'id', 'user', 'content', - 'child', + 'children', 'updated', 'article', - 'parent_id', - 'like_status', + # 'like_status', ) diff --git a/web/api/v1/blog/services.py b/web/api/v1/blog/services.py index bbb2564..3d2b92d 100644 --- a/web/api/v1/blog/services.py +++ b/web/api/v1/blog/services.py @@ -1,4 +1,4 @@ -from django.db.models import Count, Q, QuerySet +from django.db.models import Count, Prefetch, Q, QuerySet from blog.choices import ArticleStatus from blog.models import Article, ArticleTag, Category, Comment @@ -33,7 +33,14 @@ def get_queryset() -> QuerySet[Comment]: return Comment.objects.all() def comments_by_article_slug(self, article_slug: str) -> QuerySet[Comment]: - return self.get_queryset().filter(article__slug=article_slug) + return ( + self.get_queryset() + .filter(article__slug=article_slug, parent__isnull=True) + .select_related('user') + .prefetch_related( + Prefetch('parent_set', queryset=Comment.objects.all().select_related('user')), + ) + ) @staticmethod def is_valid_comment_parent(parent_id: int, article: Article) -> bool: diff --git a/web/api/v1/blog/views.py b/web/api/v1/blog/views.py index 76ceeac..fa653b3 100644 --- a/web/api/v1/blog/views.py +++ b/web/api/v1/blog/views.py @@ -40,7 +40,7 @@ def post(self, request): class CommentListView(ListAPIView): - serializer_class = serializers.CommentSerializer + serializer_class = serializers.CommentListSerializer def get_queryset(self): slug = self.kwargs['article_slug'] diff --git a/web/blog/static/blog/js/detail.js b/web/blog/static/blog/js/detail.js index 055d51b..5761d78 100644 --- a/web/blog/static/blog/js/detail.js +++ b/web/blog/static/blog/js/detail.js @@ -1,6 +1,5 @@ $(function () { const slug = window.location.pathname.split('/')[2] - getArticleDetail(slug); getCommentList(slug) $('#createCommentForm').submit(createComment); @@ -86,13 +85,13 @@ function createComment(e) { content: this.textComment.value, parent_id: this.parent_id.value, } - console.log('data', data); $.ajax({ url: '/api/v1/blog/comments/', type: 'post', data: data, success: function (data) { -// location.reload(); + const slug = window.location.pathname.split('/')[2] + getCommentList(slug); }, error: function (data) { $(".help-block").remove() @@ -127,5 +126,59 @@ function getCommentList(slug) { } function handleComments(data) { - console.log('data', data); + const commentList = $('#paginationComment') + console.log('data', data) + const template = data.results.map(comment => commentTemplate(comment)).join(''); + $('#commentCount').html(`Comments (${data.count})`) + commentList.empty(); + commentList.append(template); +} + +function commentChildTemplate(comment) { + const template = ` +