在Django中使用Ajax独立提交两个表单仅一个生效的问题
Django中两个Ajax POST表单仅一个可提交的问题
我尝试在Django中用Ajax提交两个POST表单,但只有第一个表单能正常以POST方式提交,第二个失败。推测问题出在JavaScript代码里,但搞不懂为什么第一个正常第二个不行,搜了很多地方也没找到匹配的解决方案。
views.py代码
import os import time from datetime import datetime from django.http import HttpResponse, StreamingHttpResponse from django.shortcuts import render from utils.camera_streaming_widget import CameraStreamingWidget # Camera feed def camera_feed(request): stream = CameraStreamingWidget() frames = stream.get_frames() return StreamingHttpResponse(frames, content_type='multipart/x-mixed-replace; boundary=frame') def detect(request): stream = CameraStreamingWidget() success, frame = stream.camera.read() if success: status = True else: status = False return render(request, 'detect_barcodes/detect.html', context={'cam_status': status}) def dados(request): if request.method == 'POST': name = request.POST['name'] print('HELLO') return HttpResponse(name) def dados_cod(request): if request.method == 'POST': cod = request.POST['cod'] print(cod) return HttpResponse(cod)
HTML模板代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" ></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <title>Detect Barcodes</title> <style type="text/css"> .navbar-brand { font-size: xx-large; } </style> </head> <body> <nav class="navbar navbar-expand-lg navbar-light" style="background-color: #3c8f56;"> <div class="container-fluid container-md"> <a class="navbar-brand" href="{% url 'detect_barcodes' %}"></a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div id='NomeDoSem'><h2>Sistema de Presença</h2></div> <div class="dropdown"> <button class="btn btn-success dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false"> Nome do Seminario </button> <ul class="dropdown-menu"> <form id="post-name"> {% csrf_token %} <div class="input-group mb-3"> <input type="text" class="form-control" aria-describedby="basic-addon2" id="name" name="name"> <div class="input-group-append"> <button class="btn btn-outline-secondary" type="submit">Enviar</button> </div> </div> </form> </ul> </div> </div> </nav> <div class="container"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script> {% block content %} {% endblock content %} </div> <br> <form name="post-cod"> {% csrf_token %} <div class="input-group mb-3"> <input type="text" class="col-md-offset-5 col-md-5 " id="cod" name="cod" style="border: 0.5px solid gray;"> <div class="input-group-append"> <button class="btn btn-outline-secondary" type="submit">Enviar</button> </div> </div> </form> <script text="text/javascript"> $('#post-name').submit(function(e){ e.preventDefault(); $.ajax({ type:'post', url:'{% url \"dados\" %}', data:{ name:$('#name').val(), csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val(), }, success: function(data){ $('#NomeDoSem').empty() $('#NomeDoSem').html('<h2>'+data+'</h2>') } }); }); $('#post-cod').submit(function(b){ b.preventDefault(); $.ajax({ type:'post', url:'{% url \"dados_cod\" %}', data:{ cod:$('#cod').val(), csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val(), }, success: function(data){ alert('cpf') } }); }); </script> </body> </html>
问题原因及修复方案
问题核心在于第二个表单的事件绑定失败:你给第二个表单设置的是name="post-cod",但JavaScript里用的$('#post-cod')是根据id属性查找元素的选择器,而非name属性,导致事件根本没绑定到表单上,点击提交时会走默认表单提交逻辑,而非Ajax。
修复步骤
修正表单选择器匹配:
- 要么给第二个表单添加
id="post-cod"属性,保持选择器不变; - 要么把JavaScript选择器改成
$('form[name="post-cod"]'),匹配name属性。
- 要么给第二个表单添加
优化CSRF Token获取:
直接取页面所有csrf token可能在多表单场景下出错,建议限定在当前表单内获取,用$(this).find('input[name=csrfmiddlewaretoken]').val()替代全局查找。修正Django模板URL写法:
模板里的URL标签不需要转义引号,{% url "dados_cod" %}即可,多余的转义不影响但不符合规范。
修改后的代码示例
调整后的HTML表单
<form id="post-cod"> {% csrf_token %} <div class="input-group mb-3"> <input type="text" class="col-md-offset-5 col-md-5 " id="cod" name="cod" style="border: 0.5px solid gray;"> <div class="input-group-append"> <button class="btn btn-outline-secondary" type="submit">Enviar</button> </div> </div> </form>
调整后的JavaScript
$('#post-cod').submit(function(b){ b.preventDefault(); $.ajax({ type:'post', url:'{% url "dados_cod" %}', data:{ cod:$('#cod').val(), csrfmiddlewaretoken: $(this).find('input[name=csrfmiddlewaretoken]').val(), }, success: function(data){ alert('cpf') } }); });
内容的提问来源于stack exchange,提问作者Eduardo May Argenta
相关产品推荐
相关产品推荐

