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

通过Vue向Django提交城市评论时触发KeyError与MultiValueDictKeyError问题排查

解决Django API的MultiValueDictKeyError及Vue POST请求无响应问题

看起来你遇到的核心问题是直接访问request.data中不存在的键导致的MultiValueDictKeyError,再加上一些代码细节上的小问题,导致评论提交接口始终无法正常工作。咱们一步步拆解和修复:

1. 直接原因:未处理缺失的请求字段

在你的CityReviewList的post方法中,你用了request.data['Review']这种写法——如果前端没有传递这个字段,或者字段名拼写错误,Django就会抛出MultiValueDictKeyError。这也是你直接测试API时触发错误的原因。

修复方案:用.get()方法安全获取字段

把所有直接访问request.data键的代码,替换成.get()方法,这样即使字段缺失也不会报错,还能设置默认值适配模型的可选字段:

def post(self, request, slug, format=None):
    try:
        city = City.objects.get(slug=slug)
        # 安全获取字段,给可选字段设置默认值
        review_content = request.data.get('Review', '')
        traveler_name = request.data.get('TravelerName', '')
        picture = request.data.get('Picture', None)
        
        # 修复变量名冲突:不要用模型类名(Review)当变量名
        # 优化slug生成,避免重复(因为模型中slug是unique=True)
        from django.utils.text import slugify
        base_slug = slugify(traveler_name)
        review_slug = base_slug
        counter = 1
        while Review.objects.filter(slug=review_slug).exists():
            review_slug = f"{base_slug}-{counter}"
            counter += 1
        
        # 创建评论
        Review.objects.create(
            City=city,
            Review=review_content,
            TravelerName=traveler_name,
            Picture=picture,
            slug=review_slug
        )
        return Response({'message': 'Review created successfully'}, status=201)
    except City.DoesNotExist:
        return Response({'error': 'City not found'}, status=404)

2. 变量名冲突问题

你原来的代码里写了Review = request.data['Review'],这里的Review是你的模型类名,把它作为变量名会导致代码混淆,甚至可能引发意外错误——上面的修复已经把这个变量改成了review_content,避免冲突。

3. Vue端的优化建议

你的Vue代码大部分是对的,但有几个可以优化的点:

  • 后端已经通过URL中的slug获取了对应的城市,不需要再传递City字段到formData里,可以删掉formData.append('City', this.review.city);
  • 确保this.review.city确实是目标城市的slug,和URL中的参数匹配
  • 可以在上传前做简单的字段校验,比如确保Review和TravelerName不为空,避免无效请求

修改后的Vue方法示例:

uploadImageToServer() {
    // 简单校验
    if (!this.review.Review || !this.review.TravelerName) {
        console.log("请填写必填字段");
        return;
    }
    
    let formData = new FormData();
    formData.append('Review', this.review.Review);
    formData.append('TravelerName', this.review.TravelerName);
    if (this.myimg) { // 只有选择了图片才添加
        formData.append('Picture', this.myimg, this.myimg.name);
    }
    
    axios.post(`http://127.0.0.1:12222/api/v1/cities/${this.review.city}/reviews/`, formData)
        .then(res => {
            console.log(res);
            // 提交成功后重置表单
            this.review.Review = '';
            this.review.TravelerName = '';
            this.myimg = null;
        })
        .catch(err => {
            console.error("提交失败:", err.response?.data || err.message);
        })
}

4. 额外注意事项

  • 确保Django的MEDIA_URL和MEDIA_ROOT配置正确,否则图片上传后无法访问
  • 测试API时,用Postman等工具先测试,确保传递的字段名和后端期望的完全一致(比如Review和TravelerName的大小写)
  • 给视图添加异常捕获(比如City.DoesNotExist),返回更友好的错误响应,方便调试

按照这些修改后,你的评论提交接口应该就能正常工作了,Vue端的请求也不会再无响应~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 17:52:31