Django添加第二/三篇博文评论时报视图未返回HttpResponse错误如何解决
问题原因
你的报错触发有三个核心原因:
- 模板ID重复:循环渲染每篇博文的评论表单时,所有表单、提交按钮都使用了同一个id,HTML中id是唯一标识,重复后JS永远只能获取到第一篇博文的表单内容,提交后续博文评论时序列化的数据完全错误。
- 表单字段名不匹配:
PostCommentForm需要接收post字段关联对应博文,但你模板里隐藏下拉框的name属性写的是video,导致表单接收不到关联博文的参数,验证直接失败。 - 视图逻辑不全:当前的
add_comment_post视图没有覆盖所有分支:- 非POST请求时没有返回响应
- 表单验证失败时没有返回响应
两种情况都会直接返回None,触发你遇到的ValueError。
修复步骤
1. 补全视图逻辑,覆盖所有返回分支
修改add_comment_post视图代码:
@login_required def add_comment_post(request): if not request.user.is_active: return render(request, 'personal/violated.html') if request.method == 'POST': if request.POST.get('action') == 'delete': id = request.POST.get('nodeid') c = PostCommentIDF.objects.get(id=id) c.delete() return JsonResponse({'remove': id}) else: comment_form = PostCommentForm(request.POST) if comment_form.is_valid(): user_comment = comment_form.save(commit=False) user_comment.author = request.user user_comment.save() result = comment_form.cleaned_data.get('content') user = request.user.username return JsonResponse({'result': result, 'user': user}) # 新增表单验证失败的返回逻辑 return JsonResponse({'status': 'error', 'msg': '表单验证失败'}, status=400) # 新增非POST请求的返回逻辑 return JsonResponse({'status': 'error', 'msg': '请求方式错误'}, status=405)
2. 修复模板ID重复和字段名问题
循环渲染表单时用博文ID生成唯一标识,同时修正隐藏字段的name属性:
{% for video in video %} .... <!-- 用video.id生成唯一表单id --> <form id="Postcommentform_{{ video.id }}" class="Postcommentform" method="post" style="width: 100%;"> {% load mptt_tags %} {% csrf_token %} <!-- 把name从video改成post,匹配表单的字段名 --> <select class="d-none" name="post" id="id_post_{{ video.id }}"> <option value="{{ video.id }}" selected></option> </select> <div class="d-flex"> <label class="small font-weight-bold">{{ comments.parent.label }}</label> {{ comments.parent }} {{comments.content}} <!-- 按钮用class绑定事件,value绑定当前表单的唯一id --> <button value="Postcommentform_{{ video.id }}" class="Postnewcomment d-flex justify-content-end btn btn-primary" type="submit" style="color: white; border-radius: 0;">Post</button> </div> </form> .... {% endfor %}
3. 适配AJAX代码,支持多表单提交
修改JS逻辑,适配唯一表单ID:
// 用class绑定点击事件,不再使用重复id $(document).on('click', '.Postnewcomment, #Postnewcommentinner', function (e) { e.preventDefault(); var formId = $(this).attr("value"); var currentForm = $("#" + formId); var placement = formId; if ($(this).attr("value") == "Postnewcommentform") { placement = "becomm"; } $.ajax({ type: 'POST', url: '{% url "video:addcomment_post" %}', data: currentForm.serialize(), cache: false, success: function (json) { console.log(json); $('<div id="" class="my-2 p-2" style="border: 1px solid grey"> \ <div class="d-flex bd-highlight mb-3">\ <div class="p-2 bd-highlight">' + json['user'] + '</div> <div class="ml-auto p-2 bd-highlight">Posted: Just now!</div> \ </div>\ <div>' + json['result'] + '</div> \ <br>\ </div>').insertAfter(currentForm); // 重置当前点击的表单,而非固定的第一个表单 currentForm[0].reset(); }, error: function (xhr, errmsg, err) { console.log(xhr.responseText); } }); })
内容的提问来源于stack exchange,提问作者Ahmed
相关产品推荐
相关产品推荐

