【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_count
、favorite_count
、reply_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 路由,减少手写代码量。
三、总结
-
后端
- 设计
Comment
模型,支持多级评论、点赞、收藏。 - 通过
like_count()
、favorite_count()
动态统计点赞/收藏数。 - API 设计清晰,支持
like()
、favorite()
、comment_count()
接口化点赞/收藏/计数。
- 设计
-
前端
- 提供接口
/api/comments/
获取文章评论。 /api/comments/<id>/like/
&/api/comments/<id>/favorite/
处理点赞/收藏操作。/api/comments/comment_count/
获取文章评论总数。
- 提供接口
这套 Django DRF 评论系统 既灵活又高效,并且结构清晰可扩展,适用于各种前后端分离项目! 🚀