Search code examples
djangodjango-rest-frameworkdjango-formsdjango-widgetdjango-model-field

check that the dates are entered correctly in a form


I have a form to create events and I want to check that the dates are correct: end date greater than the start date or dates not before the actual date, etc... I was checking on the internet if there was any check with django for django.contrib.admin widgets but I can't find anything.

In form.hmtl:

<form method="post">
{% csrf_token %}
<table class="form form-table">
{{ form }}
<tr><td colspan="2"><button type="submit" class="btn btn-info right"> Submit </button></td></tr>
</table>
</form>

In forms.py:

class EventForm(ModelForm):
   class Meta:
     model = Event
     fields = ('classrom', 'title', 'description', 'start_time',
     'end_time', 'calendar')

   def __init__(self, *args, **kwargs):
     super(EventForm, self).__init__(*args, **kwargs)
     self.fields['start_time'].widget = widgets.AdminTimeWidget()
     self.fields['end_time'].widget = widgets.AdminTimeWidget()

In models.py:

class Event(models.Model):
classrom = models.CharField(max_length=200)
title = models.CharField(max_length=200)
description = models.TextField()
start_time = models.DateTimeField()
end_time = models.DateTimeField()

calendar = models.ForeignKey(Calendar, on_delete = models.CASCADE)

Solution

  • You can perform this check in the .clean() method of the Form [Django-doc]:

    from django.utils.timezone import now
    from django.core.exceptions import ValidationError
    
    class EventForm(ModelForm):
        class Meta:
            model = Event
            fields = ('classrom', 'title', 'description', 'start_time', 'end_time', 'calendar')
            widgets = {
                'start_time': widgets.AdminTimeWidget()
                'end_time': widgets.AdminTimeWidget()
            }
    
        def clean(self):
            cleaned_data = super().clean()
            start = cleaned_data.get('start_time')
            end = cleaned_data.get('end_time')
            if now() > start:
                raise ValidationError('start time should later than now.')
            if start > end:
                raise ValidationError('end time should later start time.')
            return cleaned_data