Manas Chaturvedi
Manas Chaturvedi

Reputation: 5560

Django: Validator for a multiple choice form field

I have a multiple choice field in my form where users are given a list of fields, and they can select a maximum of three choices. I've defined a custom validator for restricting users from selecting more than three fields.

forms.py

class EvangelizedForm(forms.ModelForm):
    area_of_interest = forms.CharField(
        max_length=1230,
        widget=forms.CheckboxSelectMultiple(
            choices=Evangelized.AREA_CHOICES),
        help_text="Areas of interest(Upto 3)")

I have defined a custom form validator named len_area in models.py as follows:

def len_area(li):
    if len(li) > 3:
        raise ValidationError("Please select a maximum of three fields only")

models.py

class Evangelized(models.Model):
    AREA_CHOICES = (
        ('Govt', 'Govt'),
        ('Entertainment', 'Entertainment'),
        ('Automobile', 'Automobile'),
        ('Careers', 'Careers'),
        ('Books','Books'),
        ('Family', 'Family'),
        ('Food', 'Food'),
        ('Gaming', 'Gaming'),
        ('Beauty', 'Beauty'),
        ('Sports','Sports'),
        ('Events', 'Events'),
        ('Business', 'Business'),
        ('Travel', 'Travel'),
        ('Health', 'Health'),
        ('Technology','Technology'),
    ) 
    area_of_interest = models.CharField(
        max_length=1280,
        validators=[len_area])

However, the ValidationError message gets thrown at the user at all times, i.e even when the selected fields are three or less than three.

What seems to be wrong with my validator function?

Upvotes: 0

Views: 2166

Answers (2)

f43d65
f43d65

Reputation: 2302

My guess is that value, returned by CheckboxSelectMultiple's value_from_datadict method, is list [u'abc', u'xyz']. Then it is converted to string [u'abc', u'xyz'] by field's to_python method (actually, it is u"[u'abc', u'xyz']"). After validators are run. Length of this string is more than 3, that's why you got ValidationError.

You should use ManyToManyField.

Upvotes: 1

Manas Chaturvedi
Manas Chaturvedi

Reputation: 5560

The reason why my validator wasn't working as intended was because the argument passed to the validator, say [u'abc', u'xyz'], was a string and not a list as I earlier thought while defining my validator. As a result, as rightly pointed out by @f43d65, the length of the argument exceeded 3 every single time, and hence the ValidationError was being raised.

I made the following changes in my validator in order for it to work as intended:

def len_area(li):
    if li.count("u'") > 3:
        raise ValidationError("Please select a maximum of three fields only")

Upvotes: 0

Related Questions