求助:Django视图POST函数无法获取数据,如何用纯JS实现无刷新提交?
问题解决:Django表单数据无法获取 + 纯JS无刷新提交实现
一、表单数据无法获取的问题排查与修复
1. HTML表单元素属性错误
表单数据提交依赖元素的name属性识别字段,你的代码存在两处关键错误:
- 标题输入框的
type写成了非法值text_name,且缺少name="text_name" - 文本域缺少
name="text_content"
修复后的表单代码:
<form method="post" class="form" id="form"> <!-- 添加id,方便JS获取 --> {% csrf_token %} <input type="text" name="text_name" placeholder="title" required/> <!-- 修正type,添加name --> <select id="text_category" name="text_category" required> {% for category in categories %} <option value="{{ category.pk }}">{{category.title}}</option> {% endfor %} </select> <textarea id="text" name="text_content" placeholder="text" required></textarea> <!-- 添加name --> <input type="submit" value="Submit"/> <!-- 修正submit标签写法 --> </form>
2. JS表单元素获取失败
你用document.getElementById('form')获取表单,但原表单只有class="form",无对应id,导致saveForm为null,事件绑定完全无效。修复方式是给表单添加id="form"(如上)。
3. JS事件名拼写错误
saveForm.addEventListener('sumbit', ...)中的sumbit是拼写错误,正确应为submit。拼写错误会导致事件无法触发,表单走默认刷新提交流程,而非你写的异步逻辑。
4. Django视图优化(可选)
由于你使用了DRF的@api_view,用request.data替代request.POST更符合DRF规范,同时添加参数校验和异常捕获避免崩溃:
@csrf_exempt @api_view(['POST']) def post_data(request): text_name = request.data.get('text_name') text_category_id = request.data.get('text_category') text_content = request.data.get('text_content') # 校验必填字段 if not all([text_name, text_category_id, text_content]): return Response({'error': '缺少必填字段'}, status=400) # 捕获分类不存在的异常 try: text_category = Category.objects.get(id=text_category_id) except Category.DoesNotExist: return Response({'error': '分类不存在'}, status=404) text_char_count = len(text_content) text = Text(name=text_name, category=text_category, content=text_content, char_count=text_char_count, created_at=datetime.now()) text.save() return Response({'id': text.id, 'date': text.created_at})
二、纯JavaScript实现表单无刷新提交
正确的无刷新提交逻辑包含三个核心步骤,修复后的form.js代码如下:
const saveForm = document.getElementById('form'); const charCount = document.getElementById('char-count'); const textContent = document.getElementById('text'); // 字符计数逻辑 textContent.addEventListener('input', () => { charCount.textContent = textContent.value.length; }); // 无刷新提交逻辑 saveForm.addEventListener('submit', async (event) => { event.preventDefault(); // 阻止默认刷新行为 const formData = new FormData(saveForm); // 自动收集所有带name的表单字段(含CSRF令牌) try { const response = await fetch('/api/text-form/', { // 使用相对路径适配不同部署环境 method: 'POST', body: formData }); if (!response.ok) { throw new Error(`请求失败:${response.status}`); } const data = await response.json(); console.log('提交成功:', data); // 提交成功后的额外操作:清空表单、重置计数 saveForm.reset(); charCount.textContent = '0'; } catch (error) { console.error('提交出错:', error); // 可在此添加前端错误提示逻辑 } });
关键注意事项
- CSRF令牌:表单中的
{% csrf_token %}会被FormData自动收集,无需额外处理Django的CSRF验证 - 相对路径:避免使用硬编码的绝对路径,确保部署时请求地址正确
- 错误处理:通过
try/catch和响应状态检查,覆盖请求失败的场景
内容的提问来源于stack exchange,提问作者nofamenoname
相关产品推荐
相关产品推荐

