如何为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
相关产品推荐
相关产品推荐

