Reputation: 52343
I have a form that requires some fields only if a radio button is selected.
If i set the field as "required=True" then it behaves has desired, but how do I get it to behave as "required=False" when the radio button is not selected?
I'm thinking I'd go for a default of required=False
then check the value of the radio button in form.clean()
and call for a clean_<field>
for those fields that are now required, but it doesn't seem to be that simple. Or is it?
Alternatively I'd start with required=True
, then in form.clean()
check the value of the radio button, and if not set then just remove any errors raised from the no-longer-required fields?
Upvotes: 1
Views: 3128
Reputation: 52343
Oh, looky, I worked it out all by my lonesome... the latter option is indeed much simpler than trying to find and call validation routines on specific fields. Much easier to squash the errors:
Set all the potentially required fields as required=True
then in form.clean()
test the value of the other field and, if necessary, just delete the errors from self.errors
# payment type
payment_method = forms.CharField(max_length="20", required=True)
payment_method.widget=forms.RadioSelect(choices=PAYMENT_METHOD_CHOICES)
# credit card details
cc_number = CreditCardField(max_length=20, required=True)
cc_name = forms.CharField(max_length=30, required=True)
cc_expiry = ExpiryDateField(required=True)
cc_ccv = VerificationValueField(required=True)
def clean(self):
data = super(PaymentForm, self).clean()
if data.get('payment_method') == 'paypal':
for field_name in ['cc_number','cc_name','cc_expiry','cc_ccv']:
if field_name in self.errors:
del self.errors[field_name]
Upvotes: 2
Reputation: 37364
form.clean
is the right place to do this. What's not right is calling clean_<field>
for other fields - they will have already been cleaned and their values will be in the cleaned_data
dict.
Take a look at the example in the docs: https://docs.djangoproject.com/en/dev/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other It runs through almost exactly this scenario, showing how you can test one field based on another and how you can either raise a form-level error when missing or bind the error to one of the fields.
Upvotes: 1