1

我需要向我的 ModelForm 添加一个条件验证。

下面是我的Listing模型。

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

仅当 type == 'event'时才需要场地。如果 type == 'release',我希望场地是必需的=False

我该怎么办?

谢谢

4

2 回答 2

4

首先Listing.venue需要允许空值

venue = models.ForeignKey(Venue, blank=True, null=True)

然后你ModelForm需要一个干净的方法。类似于以下内容

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")
于 2013-08-20T08:51:43.693 回答
2

您提到了进行ModelForm验证,但您应该问自己此规则是否特定于使用表单创建对象,或者它是否是您的数据模型本身固有的。如果是后者,那么做模型验证更有意义。

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')

这将在ModelForm验证期间被调用,因此在那里将产生相同的效果,但在模型上定义它允许您在任何时候使用该Model.full_clean()方法检查数据的一致性。

正如 Iain 指出的那样,您首先需要允许venue.

venue = models.ForeignKey(Venue, blank=True, null=True)
于 2013-08-20T11:49:35.297 回答