Reputation: 2312
I need to add a conditional piece of validation to my ModelForm.
Below is my Listing
Model.
LISTING_TYPES = (
('event', 'event'),
('release', 'release')
)
class Listing(models.Model):
title = models.CharField(max_length=255, verbose_name='Listing Title')
type = models.CharField(max_length=255, choices=LISTING_TYPES, verbose_name='Listing Type')
slug = models.SlugField(max_length=100)
content = models.TextField(verbose_name='Listing Overview')
competition = models.TextField()
date_start = models.DateTimeField()
time_start = models.CharField(max_length=255)
date_end = models.DateTimeField()
time_end = models.CharField(max_length=255)
pub_date = models.DateTimeField('date published', auto_now_add=True)
venue = models.ForeignKey(Venue)
class ListingForm(ModelForm):
date_start = forms.DateField(input_formats=DATE_INPUT_FORMATS)
date_end = forms.DateField(input_formats=DATE_INPUT_FORMATS)
class Meta:
model = Listing
Venue should only be required if type == 'event'. If type == 'release', I want venue to be required=False
How can I go about this?
Thanks
Upvotes: 1
Views: 1894
Reputation: 49092
You mentioned doing ModelForm
validation, but you should ask yourself if this rule is specific to creating objects with forms, or whether it is inherent in your data model itself. If it's the latter, then doing model validation makes more sense.
from django.core.exceptions import ValidationError
class Listing(models.Model):
...
def clean(self):
super(Listing, self).clean()
if self.type == 'event' and not self.venue:
raise ValidationError('A venue is required for events')
This will be called during ModelForm
validation, so it will have the same effect there, but defining it on the model allows you to check the consistency of your data at any point with the Model.full_clean()
method.
As Iain points out, you first need to allow null values for venue
.
venue = models.ForeignKey(Venue, blank=True, null=True)
Upvotes: 2
Reputation: 32294
First Listing.venue
needs to allow null values
venue = models.ForeignKey(Venue, blank=True, null=True)
Your ModelForm
then needs a clean method. Something like the following
def clean(self):
cleaned_data = super(ListingForm, self).clean()
venue = cleaned_data.get("venue")
type = cleaned_data.get("type")
if type == 'event' and not venue:
raise forms.ValidationError("A venue is required for events")
Upvotes: 4