You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为DRF的PostDetail视图添加POST方法实现评论功能?

解决DRF中PostDetail视图添加评论提交功能的方案

先修正模型核心问题,再逐步实现评论提交功能:

一、修正模型字段类型

当前Answers和Like模型使用OneToOneField,会导致一个帖子只能关联一条评论/一个点赞,完全不符合多评论/多点赞需求,必须改为ForeignKey:

修改models.py

class Answers(models.Model):
    # 替换OneToOneField为ForeignKey,添加related_name方便反向查询
    post = models.ForeignKey(Createpost, on_delete=models.CASCADE, related_name='comments')
    body = models.TextField()
    author = models.ForeignKey(User,on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    Updated_At = models.DateTimeField(auto_now=True)
    active = models.BooleanField(default=False)

    def __str__(self):
        return 'Comment {} by {} '.format(self.body,self.author)

class Like(models.Model):
    # 替换OneToOneField为ForeignKey,添加related_name方便反向查询
    post = models.ForeignKey(Createpost, on_delete=models.CASCADE, related_name='likes')
    author = models.ForeignKey(User,on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        unique_together = ('post','author',)

同时简化Createpost模型的属性方法,利用related_name提升查询效率:

class Createpost(models.Model):
    # 其他原有字段保持不变

    @property
    def total_likes(self):
        return self.likes.count()

    @property
    def likes(self):
        return [like.author.username for like in self.likes.all()]
    
    @property
    def total_comments(self):
        return self.comments.count()

    @property
    def comments(self):
        comment_list = []
        for comment in self.comments.all().order_by('-created_at'):
            comment_list.append({
                'body': comment.body,
                'username': comment.author.username,
                'created_at': comment.created_at
            })
        return comment_list

二、完善评论序列化器

修改serializers.py中的CommentSerializer,使其正确处理评论的序列化和反序列化:

class CommentSerializer(serializers.ModelSerializer):
    # 只读字段,返回评论作者用户名和创建时间
    username = serializers.ReadOnlyField(source='author.username')
    created_at = serializers.ReadOnlyField()

    class Meta:
        model = Answers
        # 仅允许用户输入评论内容,其他字段由视图自动填充
        fields = ('id', 'body', 'username', 'created_at')
        exclude = ['post', 'author', 'Updated_At', 'active']

三、修改PostDetail视图添加评论提交逻辑

在views.py中更新PostDetail类,添加post方法处理评论提交请求,同时限制仅登录用户可提交:

from rest_framework import status
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from .models import Createpost, Answers
from .serializers import PostSerializer, PostDetailSerializer, CommentSerializer

class PostDetail(generics.RetrieveUpdateDestroyAPIView):
    # 添加IsAuthenticated权限,仅登录用户可提交评论
    permission_classes = (IsAuthorOrReadOnly, IsAuthenticated,)
    queryset = Createpost.objects.all()
    serializer_class = PostDetailSerializer

    def post(self, request, *args, **kwargs):
        # 获取当前请求的帖子对象
        post = self.get_object()
        # 序列化用户提交的评论数据
        serializer = CommentSerializer(data=request.data)
        if serializer.is_valid():
            # 自动关联帖子和当前登录用户,保存评论
            serializer.save(post=post, author=request.user)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        # 验证失败返回错误信息
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

四、配置认证(必要)

确保在settings.py中配置DRF认证类,让系统识别登录用户:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    ],
}

使用方式

向帖子详情URL(例如/posts/<post_id>/)发送POST请求,请求体携带body字段即可提交评论:

{
    "body": "这是一条新评论"
}

提交成功后会返回评论详情,再次请求帖子详情时,com_ments字段会包含这条新评论。

内容的提问来源于stack exchange,提问作者Adhishraya Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 05:50:27