Suppose we have a form to collect user data and three of the fields are for contact details - mail, phone and fax. We want users to fill with valid data at least one of them. In other words they must have required=False and their validation should be done both in clean_FIELDNAME() and clean(). Usually in order to check whether a field has a fair value, we check in cleaned_data keys. But these fields are not mandatory and they always will be present in cleaned_data, even when they are empty. Therefore we need to verify not only the keys but also the values. I propose the following simple solution:
clnd_data = super(MyForm, self).clean()
cnts = ['email','phone','fax']
if not [k for k in cnts if clnd_data.get(k, '').strip()]:
raise forms.ValidationError(_(u'Please enter at least one.'))
return clnd_data
Ilian proposed different approach:
clnd_data = super(MyForm, self).clean()
cnts = ['email','phone','fax']
if any([f for f in cnts if clnd_data.get(f, None)]):
return clnd_data
else:
raise forms.ValidationError(_('Please ...'))
Well done, but I will offer a small improvement.
ReplyDeleteIf you do not have a specific field type for phone/fax and use CharField you need to strip spaces after getting the value. Otherwise if I enter " "(3 spaces) in any of them it will pass the check.
Right. Code changed. Thanks.
ReplyDeleteif any([field for field in cnts if cleaned_data.get(field, None)]):
ReplyDeletereturn cleaned_data
else:
raise forms.ValidationError(_('Please ...'))