Saturday 7 May 2011

At least one field of the form is required

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 ...'))

3 comments:

  1. Well done, but I will offer a small improvement.
    If 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.

    ReplyDelete
  2. Right. Code changed. Thanks.

    ReplyDelete
  3. if any([field for field in cnts if cleaned_data.get(field, None)]):
    return cleaned_data
    else:
    raise forms.ValidationError(_('Please ...'))

    ReplyDelete