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

Django开发评论提交接口报错:BlogPostComment.blog_post需为BlogPost实例

问题原因

错误核心是给BlogPostComment.blog_post外键字段传入了字符串'Test',而Django外键字段要求必须传入对应关联的模型实例或者主键ID。同时存在序列化器使用不规范、字段传值逻辑冗余的问题:

  • 不应该直接调用serializer.create()传入原始的request.data,序列化器调用is_valid()校验通过后,只有validated_data是经过转换的合法数据
  • 路由已经携带了博客的slug参数url,完全可以后端直接查询对应的博文实例,不需要前端传递blog_post字段,避免传值错误
  • 评论发布用户可以直接从请求对象request.user获取,不需要前端传递,安全性更高

解决方案

1. 修复视图代码

添加DRF函数视图必要的装饰器,通过路由slug查询博文实例,后端注入关联字段:

from rest_framework.decorators import api_view
from rest_framework.response import Response
from django.shortcuts import get_object_or_404
from .models import BlogPost
from .serializers import BlogPostCommentSerializer

@api_view(['POST'])
def CreateComment(request, url):
    # 用路由中的slug查询对应的博文实例,不存在直接返回404
    blog_post = get_object_or_404(BlogPost, urlpattern=url)
    serializer = BlogPostCommentSerializer(data=request.data)
    # 校验不通过直接返回错误信息
    if serializer.is_valid(raise_exception=True):
        # save方法支持传入额外关联字段,不需要前端传递
        serializer.save(blog_post=blog_post, user=request.user)
        return Response(serializer.data, status=201)
    return Response(serializer.errors, status=400)

2. 简化序列化器代码

不需要前端传递关联字段,直接移除对应的字段定义:

class BlogPostCommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = BlogPostComment
        fields = ['body'] # 仅保留需要用户输入的评论内容字段

3. 修复模型潜在报错

BlogPostComment的__str__方法直接拼接模型实例会触发类型错误,需要转成字符串:

class BlogPostComment(models.Model):
    # 原有字段不变
    def __str__(self):
        return f"{str(self.blog_post)} | {str(self.user)}"

4. 前端AJAX请求调整

  • 请求体仅需要传递body字段即可,不需要再传blog_post、user字段
  • 请求头需要携带CSRF令牌:Django默认开启CSRF校验,AJAX请求需要在请求头添加X-CSRFToken字段,值从站点cookie的csrftoken字段获取
  • 如果允许未登录用户提交评论,可自行调整user外键的约束,设置null=True, blank=True即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 20:09:03