django clean_field not reading a form field

Viewed 237

I want my code to raise an error if: User selected role=="Other" AND they left field "other_role" blank.

I made a clean function, but when I try and reference the field "other_role", it always shows up as None, even when the form is filled.

How can I reference another field?

PS: I don't want to have to explicitly define that field again in my form class because that will mess up the order my forms are rendered.

class AttendeeForm(forms.ModelForm):
    # birth_date = forms.DateField(widget=forms.TextInput(attrs={
    #    'class':'datepicker'
    #}))
    class Meta:
        model = Attendee
        fields= ('birth_date', 'degrees','area_of_study','role','other_role','institute', 'phone_number')
        widgets = {
            'birth_date': DateInput()
        }
        help_texts = {
            'degrees': 'List your degrees. Separate with commas.',
            'area_of_study': 'List your primary field of study or research. If neither are applicable, write your area of practice.',
            'institute': 'Professional Affiliation. If retired, enter your most recent affiliation.'
        }

    def clean_role(self):
        cd = self.cleaned_data
        print(cd.get("other_role"))
        if cd['role'] == 'OTHER':
            if cd.get("other_role") is not False:
                raise forms.ValidationError("You need to specify your role if you picked 'Other'")
        return cd['role']

update

I'm able to almost make it work by changing my function name to clean() and returning self.cleaned_data. The problem with this approach is that the error message raised appears at the top of all my forms instead of next to the actual form.

1 Answers

To run validation against multiple fields you should override the clean() method

To assign an error to a particular field you can pass a dictionary to ValidationError where the key is the field name:

class AttendeeForm(forms.ModelForm):
    ...

    def clean(self):
        cleaned_data = super().clean()
        role = cleaned_data.get('role')
        other_role = cleaned_data.get('other_role')
        if role == 'OTHER' and not other_role:
            raise ValidationError({'other_role': 'You need to specify your role if you picked "Other"'})
        return cleaned_data
Related