Django+Ajax评论更新功能误创建新对象的解决方法
Django+Ajax评论编辑提交后新建而非更新的问题解决
问题根源
- 前端字段覆盖错误:编辑请求成功后,你先给
#id赋值评论ID,紧接着又赋值视频ID,导致最终#id存储的是视频ID,后端无法识别要编辑的评论。 - 后端接口未区分新增/编辑:当前
ajaxComment接口只做评论创建逻辑,没有判断是否传入了待编辑的评论ID,所以无论编辑还是新增都创建新评论。 - 前端未明确操作类型:表单提交时没有明确是新增还是编辑操作,后端无法针对性处理。
解决方案
1. 修复前端编辑逻辑的字段赋值问题
修改Ajax编辑成功后的代码,用不同隐藏字段分别存储评论ID和视频ID,避免覆盖:
// Edit $('.comment-wrapper').on("click", ".btn-edit", function(){ console.log("Edit Button Cliked"); let id = $(this).attr("data-cid"); console.log(id); mydata = {cid:id} $.ajax({ url: "{% url 'edit-comment' %}", method:"POST", data:mydata, headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() }, success: function(data){ console.log(data); // 用独立隐藏字段存储评论ID和视频ID $("#comment_id").val(data.id); $("#video_id").val(data.video); $("#comment").val(data.comment); console.log(data.id); }, }) })
同时在表单中新增两个隐藏字段:
<form id="comment_form"> <input type="hidden" id="comment_id" name="comment_id" value=""> <input type="hidden" id="video_id" name="video_id" value=""> <textarea id="comment" name="comment"></textarea> {% csrf_token %} <button type="submit">提交</button> </form>
2. 修改表单提交的Ajax逻辑
提交时根据#comment_id是否有值区分操作类型,传递正确参数:
$(document).on("submit", "#comment_form", function(e){ e.preventDefault(); let _comment = $("#comment").val(); let _comment_id = $("#comment_id").val(); let _video_id = $("#video_id").val(); console.log("send button clicked"); $.ajax({ type: "POST", url: "{% url 'save-comment' %}", data:{ comment_id: _comment_id, video_id: _video_id, comment: _comment, csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(), }, success: function(response){ console.log(response); // 重置表单状态 $("#comment_id").val(""); $("#comment").val(""); // 可选:更新页面中对应评论的显示内容 }, error: function(xhr){ console.log(xhr.responseText); } }) })
3. 重构后端接口,支持新增与编辑
修改ajaxComment函数,根据comment_id判断执行创建或更新逻辑:
from django.http import JsonResponse def ajaxComment(request): if request.method == "POST": video_id = request.POST.get("video_id") comment_content = request.POST.get("comment") comment_id = request.POST.get("comment_id") user = request.user if not user.is_authenticated: return JsonResponse({"status": "error", "message": "请先登录"}, status=401) try: video = Video.objects.get(id=video_id) except Video.DoesNotExist: return JsonResponse({"status": "error", "message": "视频不存在"}, status=404) if comment_id: # 编辑评论:仅允许编辑当前用户的评论 try: comment = Comment.objects.get(pk=comment_id, user=user) comment.comment = comment_content comment.save() return JsonResponse({"status": "success", "message": "评论更新成功"}) except Comment.DoesNotExist: return JsonResponse({"status": "error", "message": "评论不存在"}, status=404) else: # 新增评论 new_comment = Comment(user=user, video=video, comment=comment_content) new_comment.save() return JsonResponse({"status": "success", "message": "评论发布成功"})
同时建议移除edit_comment视图的@csrf_exempt装饰器,通过请求头传递CSRF令牌保障安全:
def edit_comment(request): if request.method == "POST": id = request.POST.get("cid") try: comment = Comment.objects.get(pk=id) comment_data = {"id": comment.id, "comment": comment.comment, "video": comment.video.id} return JsonResponse(comment_data) except Comment.DoesNotExist: return JsonResponse({"status": "error", "message": "评论不存在"}, status=404)
内容的提问来源于stack exchange,提问作者Destiny Franks
相关产品推荐
相关产品推荐

