Django点击表单提交按钮后后端未收到请求问题排查
问题根因
点击提交无请求、按钮类似禁用状态的核心原因是前端DOM结构异常+表单定义逻辑冲突,具体问题点如下:
- 模板HTML结构非法:额外在模板继承块外写
<body>标签,且表单未写</form>闭合标签,浏览器解析DOM时会出现结构错乱,无法识别按钮关联的有效表单,直接拦截提交动作 - 表单类定义错误:同时继承
forms.ModelForm和forms.Form属于多余多继承,会触发表单内部校验逻辑冲突;Key_Skill字段用了ModelMultipleChoiceField但传入的queryset是values_list返回的纯字符串列表,不符合该字段要求传入模型实例集合的规则,渲染时会报错中断HTML生成,进一步破坏表单结构 - 视图逻辑错误:POST方法里直接
pop表单fields字典的操作会破坏表单字段结构,且POST方法未接收*args,**kwargs参数,会和LoginRequiredMixin的拦截逻辑冲突
修复方案
1. 修正模板结构
删掉多余的body标签,补全标签闭合,移除按钮上多余的form属性(按钮在表单内部时不需要额外指定form id),修正后代码:
{%extends 'index.html'%} {%block body%} <div class="content-wrapper"> <h1>Create New Job</h1> <div class=""> <form action="" enctype="multipart/form-data" method="post" id="form"> {%csrf_token%} <div> {{form.as_p}} {{form.errors}} </div> <button type="submit" class="btn btn-dark" value="Submit"> Submit </button> </form> </div> </div> {%endblock%}
注意:要确认基础模板的
{%block body%}块无嵌套错误,未闭合的HTML标签会直接导致浏览器终止表单提交事件绑定。
2. 修正表单定义
去掉多余的多继承,修正字段类型和queryset规则,避免字段渲染报错:
class JobList(forms.ModelForm): job_location = forms.ModelChoiceField(queryset=CountryAndState.objects.filter(country__isnull=False).distinct()) # 不需要关联模型实例时用MultipleChoiceField,手动生成选项 Key_Skill = forms.MultipleChoiceField( choices=[(s.name, s.name) for s in skill.objects.all().distinct().order_by('name')], widget=forms.SelectMultiple, required=False ) class Meta: model = JobListing fields = ['position', 'number_of_position_opening', 'company_name', 'about_company', 'description', 'eligiblity', 'resposibility', 'city', 'job_location', 'KeySkill', 'min_experience', 'max_experience', 'min_salary', 'max_salary', 'shift_time', 'last_date_to_apply'] exclude = ['slug', 'posted'] widgets = { 'KeySkill': forms.TextInput(attrs={'type':'text'}), 'about_company': forms.Textarea(attrs={'rows': 5, 'cols': 15}), 'last_date_to_apply': forms.DateInput(attrs={'type':'date'}) } def __init__(self, user, *args, **kwargs): super().__init__(*args, **kwargs) for field in self.fields.values(): widget = field.widget if 'cols' in widget.attrs and 'rows' in widget.attrs: widget.attrs.update({'class': 'form-control pl-15 bg-transparent summernote'}) else: widget.attrs.update({'class': 'form-control pl-15 bg-transparent'}) widget.attrs['placeholder'] = field.label field.required = False # 单独处理company_name查询集,不要放在循环内重复执行 self.fields['company_name'].queryset = User.objects.filter(created_by=user, user_type=4)
3. 修正视图逻辑
移除直接修改表单fields字典的危险操作,补全方法参数,在cleaned_data层面处理额外字段的存值逻辑:
class JobCreateView(LoginRequiredMixin, TemplateView): template_name = 'Job/Recruiter/PostNewJob.html' template_name2 = 'Job/RecruiterAgency/PostNewJob.html' redirect_field_name = 'redirect_to' def get(self, request, *args, **kwargs): joblist = JobList(request.user) if request.user.user_type == 2: return render(request, self.template_name, {"form": joblist}) elif request.user.user_type == 3: return render(request, self.template_name2, {"form": joblist}) def post(self, request, *args, **kwargs): job_detail = JobList(request.user, request.POST) if job_detail.is_valid(): job_instance = job_detail.save(commit=False) # 处理多选技能字段的存值,不要直接修改表单结构 selected_skills = job_detail.cleaned_data.get('Key_Skill', []) job_instance.KeySkill = ','.join(selected_skills) job_instance.save() return redirect('/job/manage_job') if request.user.user_type == 2: return render(request, self.template_name, {"form": job_detail}) elif request.user.user_type == 3: return render(request, self.template_name2, {"form": job_detail})
额外排查项
如果改完仍无法提交,打开浏览器F12控制台查看JS报错,summernote插件如果加载失败会中断JS执行,阻止表单默认提交行为。
内容的提问来源于stack exchange,提问作者Wasim
相关产品推荐
相关产品推荐

