Reputation: 323
I tried to validate my DateField to accept only dates from today and future, but I don't know why it's accepting every passed date anyway.
My models.py file:
def present_or_future_date(value):
if value < datetime.date.today():
raise models.ValidationError("The date cannot be in the past!")
return value
class Event(models.Model):
title = models.CharField(max_length=50)
text = models.TextField()
date = models.DateField(default=datetime.now, validators=[present_or_future_date])
duration = models.TextField(default='0', blank='true')
created_at = models.DateTimeField(default=datetime.now, blank='true')
def __str__(self):
return self.title
Upvotes: 11
Views: 12928
Reputation: 673
To make sure the validation is performed, add constraints on the model in the Meta:
from django.db.models.functions import Now
from django.db import models
class Meta:
constraints = [
models.CheckConstraint(
check=models.Q(date__gte=Now()),
name='created_at_cannot_be_past_date'
)
]
Upvotes: 1
Reputation: 1910
As Benjamin said, validators are added implicitly only to ModelForms. More documentation about validators here.
If you want to be sure that no object can be created with your date condition, you should override its save method like below. Also takecare that though Django will handle naive date objects, its way better to use django.utils.timezone.now
from django.db import models
import datetime
from django.core.exceptions import ValidationError
class Event(models.Model):
title = models.CharField(max_length=50)
text = models.TextField()
date = models.DateField(default=datetime.date.today())
duration = models.TextField(default='0', blank='true')
created_at = models.DateTimeField(default=datetime.datetime.now(), blank='true')
def save(self, *args, **kwargs):
if self.date < datetime.date.today():
raise ValidationError("The date cannot be in the past!")
super(Event, self).save(*args, **kwargs)
Upvotes: 13