当前位置: 首页 > article >正文

【Django】【vue】设计一个评论模块

Django 评论模块(前后端分离 + 点赞 + 收藏 + 评论计数)


一、功能概述

基于 Django + DRF 设计的 评论模块,包含以下功能:

  • 基本评论功能(用户可以对文章进行评论,并支持多级回复)
  • 评论点赞(支持点赞/取消点赞)
  • 评论收藏(支持收藏/取消收藏)
  • 评论计数(统计文章的评论数量)
  • 嵌套评论(支持多级评论显示)

二、后端设计

(一)数据库模型(Models)

from django.db import models
from django.contrib.auth import get_user_model

User = get_user_model()

class Comment(models.Model):
    """ 评论模型 """
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='comments')  # 发表评论的用户
    content = models.TextField()  # 评论内容
    parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='replies')  # 父级评论(用于嵌套评论)
    post = models.ForeignKey('Post', on_delete=models.CASCADE, related_name='comments')  # 关联的文章
    likes = models.ManyToManyField(User, related_name='liked_comments', blank=True)  # 该评论的点赞用户
    favorites = models.ManyToManyField(User, related_name='favorited_comments', blank=True)  # 该评论的收藏用户
    created_at = models.DateTimeField(auto_now_add=True)  # 评论创建时间
    updated_at = models.DateTimeField(auto_now=True)  # 评论更新时间

    class Meta:
        ordering = ['-created_at']  # 按创建时间倒序排列

    def __str__(self):
        """ 返回评论的简要信息 """
        return f"{self.user.username} - {self.content[:20]}"

    def like_count(self):
        """ 计算该评论的点赞数 """
        return self.likes.count()

    def favorite_count(self):
        """ 计算该评论的收藏数 """
        return self.favorites.count()

    def reply_count(self):
        """ 计算该评论的回复数 """
        return self.replies.count()

注释说明

  • parent 用于存储嵌套评论,支持多级评论回复。
  • likes & favorites 使用 ManyToManyField 存储点赞和收藏的用户,便于统计。
  • like_count()favorite_count()reply_count() 用于动态统计点赞数、收藏数、回复数。

(二)序列化器(Serializers)

from rest_framework import serializers
from .models import Comment

class CommentSerializer(serializers.ModelSerializer):
    """ 评论序列化器 """
    user = serializers.StringRelatedField(read_only=True)  # 直接返回用户名
    replies = serializers.SerializerMethodField()  # 处理嵌套评论
    like_count = serializers.IntegerField(source='like_count', read_only=True)  # 点赞数量
    favorite_count = serializers.IntegerField(source='favorite_count', read_only=True)  # 收藏数量
    reply_count = serializers.IntegerField(source='reply_count', read_only=True)  # 回复数量

    class Meta:
        model = Comment
        fields = ['id', 'user', 'content', 'parent', 'post', 'created_at', 'like_count', 'favorite_count', 'reply_count', 'replies']

    def get_replies(self, obj):
        """ 递归获取所有子评论 """
        return CommentSerializer(obj.replies.all(), many=True).data

注释说明

  • user 只读,返回用户名,而不是 user_id
  • get_replies() 递归获取所有子评论,确保嵌套评论显示
  • like_countfavorite_countreply_count 提供动态字段,避免额外的数据库查询。

(三)视图(Views)

from rest_framework import viewsets, permissions, status
from rest_framework.response import Response
from rest_framework.decorators import action
from .models import Comment
from .serializers import CommentSerializer

class CommentViewSet(viewsets.ModelViewSet):
    """ 评论视图集 """
    queryset = Comment.objects.all()
    serializer_class = CommentSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]  # 仅认证用户可操作,游客可读

    def perform_create(self, serializer):
        """ 绑定当前用户为评论作者 """
        serializer.save(user=self.request.user)

    def get_queryset(self):
        """ 根据 `post_id` 过滤评论,仅获取一级评论 """
        post_id = self.request.query_params.get('post')
        if post_id:
            return Comment.objects.filter(post_id=post_id, parent=None)  # 仅获取顶级评论
        return Comment.objects.none()

    @action(detail=True, methods=['post'])
    def like(self, request, pk=None):
        """ 处理点赞和取消点赞 """
        comment = self.get_object()
        if request.user in comment.likes.all():
            comment.likes.remove(request.user)
            return Response({'message': '取消点赞'}, status=status.HTTP_200_OK)
        else:
            comment.likes.add(request.user)
            return Response({'message': '点赞成功'}, status=status.HTTP_200_OK)

    @action(detail=True, methods=['post'])
    def favorite(self, request, pk=None):
        """ 处理收藏和取消收藏 """
        comment = self.get_object()
        if request.user in comment.favorites.all():
            comment.favorites.remove(request.user)
            return Response({'message': '取消收藏'}, status=status.HTTP_200_OK)
        else:
            comment.favorites.add(request.user)
            return Response({'message': '收藏成功'}, status=status.HTTP_200_OK)

    @action(detail=False, methods=['get'])
    def comment_count(self, request):
        """ 获取文章的评论总数 """
        post_id = request.query_params.get('post')
        if post_id:
            count = Comment.objects.filter(post_id=post_id).count()
            return Response({'comment_count': count}, status=status.HTTP_200_OK)
        return Response({'message': '缺少 post 参数'}, status=status.HTTP_400_BAD_REQUEST)

注释说明

  • get_queryset() 仅返回顶级评论,避免多层嵌套数据造成性能问题。
  • like() & favorite() 处理点赞/收藏逻辑,防止重复点赞
  • comment_count() 统计当前文章下的评论数量,避免前端重复请求。

(四)路由(Urls)

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import CommentViewSet

router = DefaultRouter()
router.register(r'comments', CommentViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

注释说明

  • 使用 DefaultRouter 自动生成 RESTful API 路由,减少手写代码量。

三、总结

  1. 后端

    • 设计 Comment 模型,支持多级评论点赞收藏
    • 通过 like_count()favorite_count() 动态统计点赞/收藏数
    • API 设计清晰,支持 like()favorite()comment_count() 接口化点赞/收藏/计数
  2. 前端

    • 提供接口 /api/comments/ 获取文章评论。
    • /api/comments/<id>/like/ & /api/comments/<id>/favorite/ 处理点赞/收藏操作。
    • /api/comments/comment_count/ 获取文章评论总数。

这套 Django DRF 评论系统灵活高效,并且结构清晰可扩展,适用于各种前后端分离项目! 🚀


http://www.kler.cn/a/588030.html

相关文章:

  • 【人工智能基础2】Tramsformer架构、自然语言处理基础、计算机视觉总结
  • 数字人本地部署之llama-本地推理模型
  • Skema:AI 驱动的方案到 BIM 加速工具,重塑早期设计工作流
  • superset部署记录
  • 奇安信二面
  • SpringMVC(六)异常:全局捕获与错误响应
  • Android (Kotlin) 高版本 DownloadManager 封装工具类,支持 APK 断点续传与自动安装
  • 【模拟面试】计算机考研复试集训(第五天)
  • 自然语言处理 | 文本清洗的20种核心策略:从数据噪声到信息价值
  • 7、标准库的string的常见使用
  • 加固脱壳技术:DEX动态加载对抗
  • Matlab 矢量控制和SVPWM的感应电机控制
  • 二.使用ffmpeg对原始音频数据重采样并进行AAC编码
  • 【Linux】learning notes(4)cat、more、less、head、tail、vi、vim
  • 设计模式--单例模式(Singleton)【Go】
  • LLM自动化评测
  • WEB前端学习JAVA的一些建议
  • 【Hestia Project 数据集】美国化石燃料 CO₂ 排放数据
  • 文生图技术的演进、挑战与未来:一场重构人类创造力的革命
  • 34个适合机械工程及自动化专业【论文选题】