Django表单触发MultiValueDictKeyError,点击关注/取消关注按钮报错
解决关注/取消关注功能的MultiValueDictKeyError问题
1. 修复HTML表单的核心语法错误
引发MultiValueDictKeyError的直接原因是表单的隐藏输入框属性写错了:原代码中name"userfollow"缺少了等号,导致表单提交时根本没有携带userfollow这个参数。同时,value属性应该传递用户名而非User对象本身,否则会传递对象的字符串表示(比如<User: xxx>)而非有效用户名。
修改后的表单代码片段:
<!-- 取消关注表单 --> <form action="{% url 'unfollow' %}" method="post"> {% csrf_token %} <input type="hidden" name="userfollow" value="{{ user_profile.username }}" /> <input type="submit" value="Unfollow" /> </form> <!-- 关注表单 --> <form action="{% url 'follow' %}" method="post"> {% csrf_token %} <input type="hidden" name="userfollow" value="{{ user_profile.username }}" /> <input type="submit" value="Follow" /> </form>
2. 优化视图代码,避免异常
原视图代码存在直接索引POST数据、未处理用户不存在等问题,即使修复表单后仍可能引发其他错误。优化后的视图代码如下:
from django.shortcuts import get_object_or_404, redirect, reverse from django.contrib.auth.models import User from .models import Follow def follow(request): # 安全获取POST参数,避免键不存在的异常 target_username = request.POST.get('userfollow') if not target_username: # 参数为空时返回上一页 return redirect(request.META.get('HTTP_REFERER', '/')) current_user = request.user # 用get_object_or_404替代get(),找不到用户时返回404页面 target_user = get_object_or_404(User, username=target_username) # 避免重复创建关注记录 if not Follow.objects.filter(user=current_user, user_follower=target_user).exists(): Follow.objects.create(user=current_user, user_follower=target_user) return redirect(reverse('profile', kwargs={'user_id': target_user.id})) def unfollow(request): target_username = request.POST.get('userfollow') if not target_username: return redirect(request.META.get('HTTP_REFERER', '/')) current_user = request.user target_user = get_object_or_404(User, username=target_username) # 用filter().delete()替代get().delete(),避免找不到关注记录时抛出异常 Follow.objects.filter(user=current_user, user_follower=target_user).delete() return redirect(reverse('profile', kwargs={'user_id': target_user.id}))
3. 关键优化说明
- 修复HTML的
name属性语法错误,确保表单能正确传递参数。 - 使用
request.POST.get()替代直接索引,避免键不存在时抛出MultiValueDictKeyError。 - 用
get_object_or_404处理用户查询,避免用户不存在时抛出DoesNotExist异常。 - 关注操作增加存在性检查,防止重复创建关注记录。
- 取消关注用批量删除逻辑,避免找不到记录时的异常。
内容的提问来源于stack exchange,提问作者ultrAslan05
相关产品推荐
相关产品推荐

