TidharPeer
TidharPeer

Reputation: 3797

In Django - how do i use form validation in order to prevent two fields to be selected

I have 2 fields - fieldA, fieldB - and I want to prevent the user from submitting the form.

class IntroductionForm(ModelForm):
    class Meta:
         ...
def clean_fieldA(self):
    fieldA = self.cleaned_data.get('fieldA', True)
    fieldB = self.cleaned_data.get('fieldB', True)
    if not self.instance.fieldB == fieldB and not self.instance.fieldA == fieldA:
            raise ValidationError("You may not choose both fields")

    return fieldA

At this moment I can't choose fieldA at all without getting the validation error. So how should it be done?

Thanks!

Upvotes: 0

Views: 69

Answers (4)

Victor Castillo Torres
Victor Castillo Torres

Reputation: 10811

class IntroductionForm(ModelForm):
    class Meta:
         ...
def clean_fieldA(self):
    fieldA = self.cleaned_data['fieldA']
    fieldB = self.cleaned_data['fieldB']
    if self.instance.fieldB == fieldB and  self.instance.fieldB == fieldA:
            raise ValidationError("You may not choose both fields")

    return fieldA

Upvotes: 0

Daniel Hepper
Daniel Hepper

Reputation: 29967

Check out the documentation says on Cleaning and validating fields that depend on each other. The right way to do it is to overwrite the clean() method, which gets called after the individual clean_FIELD()methods have been called.

class IntroductionForm(ModelForm):
    ....
    def clean(self):
        cleaned_data = super(IntroductionForm, self).clean()
        fieldA = bool(self.cleaned_data.get('fieldA'))
        fieldB = bool(self.cleaned_data.get('fieldB'))

        if fieldA and fieldB:
            raise forms.ValidationError("Can't select both forms")
        return cleaned_data

It is not entirely clear to if the user has to check one of the boxes. Then you would have to change the condition fieldA and fieldB to fieldA != fieldB. In this case, you could also consider using a radio box.

Upvotes: 3

TidharPeer
TidharPeer

Reputation: 3797

So this is the right solution (which works for me). Because I need to validate two fields at the same time I use clean(self) and not a specific clean_fieldA(self) - this way.

def clean(self):
    cleaned_data = super(IntroductionForm, self).clean()
    fieldA = cleaned_data.get('fieldA')
    fieldB = cleaned_data.get('fieldB')
    if fieldA and fieldB:
        raise ValidationError("You may not choose both fields!")

    return cleaned_data

Upvotes: 1

Shreeyansh Jain
Shreeyansh Jain

Reputation: 1495

You first check the fields in the clean data and the check there values.

def clean_fieldA(self):

    if 'fieldA' in self.cleaned_data and 'fieldB' in self.cleaned_data:
        if self.cleaned_data['fieldA'] != self.cleaned_data['fieldB']:
            raise forms.ValidationError(_("You may not choose both fields."))

    return self.cleaned_data['fieldA']

Hope this will help you :)

Upvotes: 0

Related Questions