如何修复Django中隐藏字段submitted_by的必填报错问题
错误原因
- 核心原因1:如果
submitted_by是关联User表的外键字段,你给隐藏输入框赋值的是user.username字符串,表单期望接收的是用户ID的整数值,验证不通过就会触发必填报错。 - 核心原因2:用前端JS赋值的方式本身存在安全漏洞,用户可以通过浏览器控制台修改隐藏字段的值,依然可以冒充其他用户提交作业。
- 额外可能原因:JS执行时DOM还未渲染完成,导致赋值失败,字段为空触发报错。
最优解决方案(推荐)
该方案完全杜绝前端篡改风险,也不会再出现必填报错:
- 修改
forms.py,把submitted_by从表单字段中移除,不需要在前端渲染这个字段:
class assignmentUploadForm(ModelForm): class Meta: model = Submissions # 移除submitted_by字段,不在前端暴露 fields = ('submitted_to', 'submission_title', 'submission_file', 'submission_status') widgets = { 'submitted_to': forms.Select(attrs={'class': 'form-control'}), 'submission_title': forms.Select(attrs={'class': 'form-control'}), }
- 修改
views.py,重写form_valid方法,后端手动赋值提交用户:
class AddAssignmentView(CreateView): model = Submissions form_class = assignmentUploadForm template_name = 'project/assignment.html' def form_valid(self, form): # 直接从请求中取当前登录用户赋值,完全避免前端篡改可能 form.instance.submitted_by = self.request.user return super().form_valid(form)
- 模板中删掉给
submitted_by赋值的JS代码即可。
原有方案的临时修复(非常不推荐,仅作问题参考)
如果一定要保留前端隐藏字段的写法,修改模板JS代码,传入用户ID且等待DOM加载完成后再赋值:
document.addEventListener('DOMContentLoaded', function() { // 赋值用户ID而不是用户名,匹配外键字段的要求 var userId = "{{ user.id }}"; document.getElementById('user').value = userId; });
内容的提问来源于stack exchange,提问作者F Nasir
相关产品推荐
相关产品推荐

