2

I have a Django form with a DateTimeField model, and I was wondering if there is a way to make sure that the date/time the user enters is always greater than the current time.

This is what I have in my form:

from django.db import models
from django import forms    
import datetime    

start_time = models.DateTimeField(
    default=datetime.datetime.now(),
    help_text='Format is: yyyy-mm-dd hh:mm:ss',
)
still.Learning
  • 1,185
  • 5
  • 13
  • 18

1 Answers1

5

add this to your model.

from django.core.exceptions import ValidationError
from django.db import models

class MyModel(models.Model):
    # ...
    # extend the validation
    def clean(self, *args, **kwargs):
        # run the base validation
        super(MyModel, self).clean(*args, **kwargs)

        # Don't allow dates older than now.
        if self.start_time < datetime.datetime.now():
            raise ValidationError('Start time must be later than now.')
Mary Marchini
  • 718
  • 5
  • 12
Francis Yaconiello
  • 10,829
  • 2
  • 35
  • 54
  • shouldn't you do this in the form rather than the model? – John Lyon Aug 30 '12 at 00:13
  • 1
    you can do it on the form or the model (https://docs.djangoproject.com/en/dev/ref/models/instances/?from=olddocs#django.db.models.Model.clean or https://docs.djangoproject.com/en/dev/ref/forms/validation/#cleaning-a-specific-field-attribute). Difference is whether or not this is a restriction of the scenario or global. if its a global restriction, do it on the model. Otherwise, do it in the form. Op made it sound like it was a global requirement. – Francis Yaconiello Aug 30 '12 at 01:06
  • where do I call this clean() method? – still.Learning Aug 30 '12 at 01:43
  • read this: https://docs.djangoproject.com/en/dev/ref/models/instances/?from=olddocs#validating-objects. TLDR: you dont, its automatic. It gets called prior to the model's `Model.save()` function. ModelForm calls it automatically when you run `form.is_valid()`, you should call it and catch any validation exceptions manually (see: https://docs.djangoproject.com/en/dev/ref/models/instances/?from=olddocs#django.db.models.Model.full_clean) when using a regular form (form isn't bound to instance and is model unaware). – Francis Yaconiello Aug 30 '12 at 01:59
  • I have another situation once I add this code. I get the following error: 'TypeError: can't compare offset-naive and offset-aware datetimes' I've googled around to figure out what it means, and found out that it occurs when you compare two datetimes where one uses timezones and the other doesn't. However, this doesnt make sense because both of the datetimes Im comparing are not using timezones. Any help please? – still.Learning Aug 30 '12 at 17:16
  • For Django 1.7+ I don't think the `super(YOUR_CLASS_NAME, self).clean(*args, **kwargs)` line is necessary/valid anymore. I get an exception thrown if I include that line in my Django 1.7 project (the message is `global name 'args' is not defined`). But, without that line, the code works for me. – Steve Jun 02 '15 at 01:05
  • @SteveSP it is still valid and VERY required if you want the model validation to work (Hint: you do). However, this snippet has had an error for the past 3 years. instead of `def clean(self):` it should read `def clean(self, *args, **kwargs):` basically, any arguments/keyword arguments that the clean function may get passed need to be passed to the parent class(es) clean functions as well. – Francis Yaconiello Jun 02 '15 at 20:05