Django单页双表单提交时第二表单要求填写第一表单必填字段报错
问题原因
- 两个表单类的
Meta配置均指定了fields = '__all__',且绑定的是同一个模型Acquisizioni_Cessioni_particella。Django会自动将模型中所有字段都纳入表单校验范围,即便你没有在表单类中显式定义。AttiPartenzePersoneForm仅显式定义了pk_persona等字段,但模型中存在必填的pk_particella字段,该字段会被自动加入表单校验规则,提交人员表单时没有传递该字段值,就会触发必填校验报错。 - 次要问题:前端第二个表单的隐藏
tipo字段渲染时用的是{{ form.tipo }}而非{{ persona.tipo }},可能导致该字段值渲染异常,不过本次报错的核心原因是第一点。
解决方案
- 替换两个表单类中的
fields = '__all__',显式指定每个表单需要校验和保存的字段,排除不需要的模型字段:
class AttiPartenzeParticelleForm(ModelForm): pk_atto = forms.ModelChoiceField(queryset=Atti.objects.all(), widget=forms.Select (attrs={'class': 'form-control'})) pk_particella = forms.ModelChoiceField(queryset=Particelle.objects.all(), widget=forms.Select (attrs={'class': 'form-control'})) capacita = forms.CharField(max_length=30, widget=forms.NumberInput (attrs={'class': 'form-control'})) tipo = forms.CharField(max_length=30, initial="fondo", widget=forms.TextInput (attrs={'class': 'form-control'})) class Meta: model = Acquisizioni_Cessioni_particella # 只保留当前表单需要的字段 fields = ['pk_atto', 'pk_particella', 'capacita', 'tipo'] class AttiPartenzePersoneForm(ModelForm): pk_atto = forms.ModelChoiceField(queryset=Atti.objects.all(), widget=forms.Select (attrs={'class': 'form-control'})) pk_persona = forms.ModelChoiceField(queryset=Persone.objects.all(), widget=forms.Select (attrs={'class': 'form-control'})) capacita = forms.CharField(max_length=30, widget=forms.NumberInput (attrs={'class': 'form-control'})) tipo = forms.CharField(max_length=30, initial="fondo", widget=forms.TextInput (attrs={'class': 'form-control'})) class Meta: model = Acquisizioni_Cessioni_particella # 只保留当前表单需要的字段 fields = ['pk_atto', 'pk_persona', 'capacita', 'tipo']
- 修复前端人员表单的
tipo字段渲染代码,将{{ form.tipo|as_crispy_field }}修改为{{ persona.tipo|as_crispy_field }},保证隐藏字段值正确传递。 - 可选优化:如果你的模型
Acquisizioni_Cessioni_particella中pk_particella和pk_persona两个字段互斥,建议给两个字段设置null=True, blank=True,避免保存数据时数据库层面抛出非空约束错误。
内容的提问来源于stack exchange,提问作者Racerider
相关产品推荐
相关产品推荐

