Django UpdateFeedback视图报错:'QueryDict' object has no attribute 'user'
Django 更新反馈视图报错:'QueryDict' object has no attribute 'user' 排查与解决
问题描述
已实现存储客户反馈的feedBack视图且运行正常,但创建更新反馈的UpdateFeedback视图运行异常,报错信息如下:
AttributeError at /UpdateFeedback/29/
'QueryDict' object has no attribute 'user'
错误原因分析
- 命名冲突:视图函数
UpdateFeedback与表单类UpdateFeedback同名,导致在视图中执行form = UpdateFeedback(request.POST)时,实际递归调用了视图函数本身,将request.POST(QueryDict类型)作为第一个参数传入,而视图函数需要的是HttpRequest对象,后续认证逻辑访问request.user时触发错误。 - 表单定义错误:
fields = ('feedBACK')未添加逗号,被解析为字符串而非元组,导致表单字段处理异常。 - 模板与表单字段不匹配:模板中textarea的
name属性为UpdateFeedBACK,但表单字段名为feedBACK,无法正确获取提交数据。 - 视图逻辑冗余:存在无意义的
UpdateFeedback(request.POST)调用,且缺少用户认证检查、异常处理(如反馈不存在的情况)。
修复步骤
1. 解决命名冲突
修改视图函数或表单类的名称,避免同名。建议视图函数遵循Django惯例使用小写加下划线命名,表单类保留大驼峰命名。
2. 修正表单定义
确保fields为元组格式,并移除模型中不存在的字段配置。
3. 匹配模板与表单字段
调整模板中textarea的name属性,与表单字段名一致。
4. 修复视图逻辑
- 使用
get_object_or_404处理反馈不存在的情况 - 添加用户认证检查
- 正确实例化更新表单(传入
instance参数) - 调整权限检查逻辑,避免未认证用户访问
- 移除冗余代码,正确保存表单数据
完整修复代码
forms.py
class UpdateFeedbackForm(forms.ModelForm): class Meta: model = ProductREVIEWS fields = ('feedBACK',) # 添加逗号确保是元组 labels = { 'feedBACK':'Change Your View' } widgets = { 'feedBACK':forms.Textarea(attrs={'class':'form-control', 'style':'font-size:13px;'}) }
views.py(更新反馈视图)
def update_feedback(request, id): feedback = get_object_or_404(ProductREVIEWS, pk=id) product_id = feedback.product.id # 检查用户是否认证且为反馈作者 if not request.user.is_authenticated or feedback.user.id != request.user.id: messages.error(request, "无权限修改该反馈") return redirect('quick_view', product_id) if request.method == "POST": # 传入instance参数绑定要更新的对象 form = UpdateFeedbackForm(request.POST, instance=feedback) if form.is_valid(): form.save() messages.success(request, "反馈已更新") return redirect('quick_view', product_id) else: # GET请求时加载原有数据 form = UpdateFeedbackForm(instance=feedback) # 如果需要返回表单页面,可调整这里的返回逻辑,原代码直接跳转,可根据需求修改 return redirect('quick_view', product_id)
urls.py
path("feedBack/<int:quick_view_id>/", views.feedBack, name="feedBack"), path("update-feedback/<int:id>/", views.update_feedback, name="update_feedback")
模板代码
{% for feedBack in AllProductFeedback %} <form action="{% url 'update_feedback' id=feedBack.id %}" method="POST" enctype="multipart/form-data"> {% csrf_token %} <textarea id="UpdateFeedBack" rows="6" style="font-size: 13px;" class="form-control" name="feedBACK" required>{{feedBack.feedBACK}}</textarea> <!-- 添加提交按钮,原代码缺少触发POST请求的逻辑 --> <button type="submit" class="btn btn-sm btn-primary mt-2">更新反馈</button> </form> {% endfor %}
额外说明
- 模板中补充了提交按钮,原代码缺少触发POST请求的入口
- 视图中增加了GET请求的处理逻辑,若需要展示带原有数据的表单页面,可修改返回逻辑为渲染模板并传入
form参数 - 增强了权限校验,未认证用户或非反馈作者无法执行修改操作
内容的提问来源于stack exchange,提问作者Mossaddak
相关产品推荐
相关产品推荐

