Reputation: 752
forms.py
class PhoneinfoForm(forms.ModelForm):
pname = forms.CharField(required=True)
pnumber = forms.IntegerField(required=True)
gname = forms.CharField(required=False)
gnumber = forms.IntegerField(required=False)
class Meta:
model = Phone_info
fields = ['pname','pnumber','gname','gnumber']
def clean(self):
cleaned_data = self.cleaned_data
pname = cleaned_data.get("pname")
pnumber = cleaned_data.get("pnumber")
gname = cleaned_data.get("gname")
gnumber = cleaned_data.get("gnumber")
if 'pname' and 'pnumber' not in cleaned_data:
raise forms.ValidationError
if 'gname' and 'gnumber' not in cleaned_data:
raise forms.ValidationError
return cleaned_data
I am trying to validate name and number. In my case, pname
and pnumber
are one set and mandatory field, that i achieved my giving required=True
.
2nd thing is gname
and gnumber
are not mandatory, but if gnumber
is entered then it is taking blank to gname
(if nothing enteredin gname it is accepting) that should not happen. If number is entered it should not accept without name or vice versa.
My code is not working for 2nd choice, how to validate this.
Thanks
Upvotes: 1
Views: 1077
Reputation: 12054
There are several bad things in your code:
1) When using forms.ModelForm
it is not needed to declare fields in a form, if corresponding model fields have same constraints. From question example, if in model Phone_info
corresponding fields have same blank
attributes as form's required
, it is not needed to declare fields again in a modelform.
2) As pname
and pnumber
are required, you don't need to check manually that they are filled. It is already done by ModelForm
. So this is odd and must be removed:
if 'pname' and 'pnumber' not in cleaned_data:
raise forms.ValidationError
3) This line will not do what expected:
if 'gname' and 'gnumber' not in cleaned_data
It will first check condition 'gnumber' not in cleaned_data
. The result will be the boolean (True/False). And then condition if 'gname' and False/True
will be applied.
What you want is:
gname = self.cleaned_data.get("gname", None)
gnumber = self.cleaned_data.get("gnumber", None)
if gname and gnumber is None:
raise forms.ValidationError("gnumber must be filled")
if gnumber is not None and not gname:
raise forms.ValidationError("gname must be filled")
4) As you've mentiond in p.3, forms.ValidationError
must be initialized when raised:
raise forms.ValidationError("Error message")
So result code:
class PhoneinfoForm(forms.ModelForm):
# delete these fields, if they are the same, as in Phone_info
pname = forms.CharField(required=True)
pnumber = forms.IntegerField(required=True)
gname = forms.CharField(required=False)
gnumber = forms.IntegerField(required=False)
class Meta:
model = Phone_info
fields = ['pname', 'pnumber', 'gname', 'gnumber']
def clean(self):
gname = self.cleaned_data.get("gname", None)
gnumber = self.cleaned_data.get("gnumber", None)
if gname and gnumber is None:
raise forms.ValidationError("gnumber must be filled")
if gnumber is not None and not gname:
raise forms.ValidationError("gname must be filled")
return self.cleaned_data
Upvotes: 1