通过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
相关产品推荐
相关产品推荐

