Derek Reynolds
Derek Reynolds

Reputation: 3503

Conditionally Require Only One Field In Django Model Form

Anyway to make a field conditionally required based on whether or not another field in the same form has been filled out?

If field1 has no data, but field2 does
    form is valid.

If field1 has no data and field2 has no data
    form is invalid

Not looking for any javascript solutions. I feel as it should be solved with django forms, but not quite sure how best to go about it.

Upvotes: 15

Views: 14734

Answers (3)

radtek
radtek

Reputation: 36370

You can also do this using the model if you know the validation will apply to all objects of this class. To use the below at the form level, use cleaned_data. Here is a sample right from Django documentation using ValidationError:

class Article(models.Model):

    status = models.CharField(max_length=75, blank=False, null=False)
    pub_date = models.CharField(max_length=75, blank=False, null=False)

    def clean(self):
        # Don't allow draft entries to have a pub_date.
        if self.status == 'draft' and self.pub_date is not None:
            raise ValidationError('Draft entries may not have a publication date.')
        # Set the pub_date for published items if it hasn't been set already.
        if self.status == 'published' and self.pub_date is None:
            self.pub_date = datetime.date.today()

Reference: Model Instance Clean, Django Validators

Here is a forms example:

class SimpleForm(forms.ModelForm):

    def clean(self):
        cleaned_data = super(SimpleForm, self).clean()  # Get the cleaned data from default clean, returns cleaned_data
        field1 = cleaned_data.get("field1")
        field2 = cleaned_data.get("field2"),

        if not field1 and not field2:
            raise forms.ValidationError('Please fill in both fields.')

        return cleaned_data

Reference: Form & Field Validation

Upvotes: 15

iElectric
iElectric

Reputation: 5819

Override .clean(self) method, check for self.cleaned_data and raise ValidationError

https://docs.djangoproject.com/en/dev/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other

Upvotes: 11

luminousmen
luminousmen

Reputation: 2169

The best solution for conditionally required field is to override clean method of the form and pop up the error on condition. For example:

clean(self):
    if self.cleaned_data.get(some_field) == 1:
        self.errors.pop(other_field, None)

Upvotes: 0

Related Questions