Django表单调用错误视图:为何转录按钮触发错误视图?
问题分析:点击转录按钮调用错误视图的原因及修复方案
问题场景
用户在transcribe.html提交文件后跳转至transcribe-complete.html,点击该页面的「Click to Transcribe」按钮时,本该触发initiate_transcription视图,但实际调用的却是transcribeSubmit视图。
核心原因
1. URL路由配置冲突
在transcribe/urls.py中,两个视图都绑定了空路径"":
urlpatterns = [ path("", views.transcribeSubmit, name = "transcribeSubmit"), path("", views.initiate_transcription, name = "initiate_transcription"), ]
Django的URL匹配规则是从上到下匹配第一个符合条件的路由,所以所有访问/transcribe/的请求都会被第一个路由拦截,initiate_transcription视图永远不会被触发。
2. JavaScript代码大小写错误(导致AJAX提交失效)
你的JS代码存在多处原生API的大小写错误,这些错误会直接导致AJAX提交逻辑失效,表单会以默认方式提交,最终还是走到了被路由优先匹配的transcribeSubmit视图:
addeventlistener→ 正确写法是addEventListenerevent.preventdefault()→ 正确写法是event.preventDefault()form.getattribute('action')→ 正确写法是form.getAttribute('action')xhr.responsetype = 'blob'→ 正确写法是xhr.responseType = 'blob'FormData、XMLHttpRequest构造函数首字母也需要大写
修复方案
步骤1:修正URL路由配置
给两个视图设置不同的路径,避免冲突:
from django.urls import path from . import views urlpatterns = [ path("", views.transcribeSubmit, name = "transcribeSubmit"), path("initiate/", views.initiate_transcription, name = "initiate_transcription"), ]
此时initiate_transcription视图的访问路径变为/transcribe/initiate/,和transcribeSubmit的路径完全区分开。
步骤2:修复JavaScript代码
修正后的JS代码:
const form = document.querySelector('form'); form.addEventListener('submit', function (event) { event.preventDefault(); const formData = new FormData(form); const xhr = new XMLHttpRequest(); xhr.open('post', form.getAttribute('action'), true); xhr.onreadystatechange = function () { console.log("ready state: ", xhr.readyState); console.log("status: ", xhr.status); } xhr.responseType = 'blob'; xhr.send(formData); });
步骤3:确保页面使用独立JS文件
确认transcribe-complete.html引用的是上述修正后的独立JS文件,避免和transcribe.html的JS逻辑冲突。
额外优化(可选)
当前transcribeSubmit视图在文件上传成功后直接渲染transcribe-complete.html,不符合PRG(Post/Redirect/Get)模式,容易导致用户刷新页面重复提交。建议改为重定向:
# 替换原return render(...)代码 return redirect('transcribe_complete') # 同时在transcribe/urls.py中添加对应路由: path("complete/", views.transcribe_complete, name="transcribe_complete") # 新增transcribe_complete视图: def transcribe_complete(request): return render(request, 'transcribe/transcribe-complete.html')
内容的提问来源于stack exchange,提问作者tthheemmaannii
相关产品推荐
相关产品推荐

