Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Validate Date & Time in Forms

I have a view where I validate date and time on form submit making sure the date + time are not past. Date and Time are two separate fields. It works, but I know its wrong way of doing it and the date+time should be validated in Django Forms.

This is in my view.py

(Probably not done the right way but it works)

my_date = request.session['reservationdate'] #in "mm/dd/yyyy" format
my_time = request.session['reservationtime'] #in "hh:mm" format
my_date_time = (my_date + ' ' + my_time + ':00') #convert to "mm/dd/yyyy hh:mm:ss"
my_date_time = datetime.strptime(my_date_time, '%m/%d/%Y %H:%M:%S') #convert to valid datetime
if datetime.now() <= my_date_time:
    #do this
else:
     ...

now my goal is to have something like the above in Django forms:

class MyForm(forms.ModelForm):  

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)

        self.fields['my_date'].required = True
        self.fields['my_time'].required = True
        ...

    def clean_my_date(self):
        my_date = self.cleaned_data['my_date']
        my_time = self.cleaned_data['my_time']
        my_date_time = (my_date + ' ' + my_time + ':00')
        my_date_time = datetime.strptime(my_date_time, '%m/%d/%Y %H:%M:%S')
        if datetime.now() <= my_date_time:
            raise forms.ValidationError(u'Wrong Date!')
        return my_date

    class Meta:
        model = MyModel
        fields = ['my_date', 'my_time', ...]

Edit:

working code:

def clean_my_time(self):
   my_date = self.cleaned_data['my_date']
   my_time = self.cleaned_data['my_time']
   my_date_time = ('%s %s' % (my_date, my_time))
   my_date_time = datetime.strptime(my_date_time, '%Y-%m-%d %H:%M:%S')
   if datetime.now() >= my_date_time:
        raise forms.ValidationError(u'Wrong Date or Time! "%s"' % my_date_time)
   return my_time

Thanks to all for the help especially xyres for his work and for being patient with me!

like image 223
WayBehind Avatar asked Dec 18 '14 17:12

WayBehind


1 Answers

You are trying to validate over multiple fields. This point is well covered by the django documentation, see https://docs.djangoproject.com/en/1.7/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other.

The job has to be done in the clean method. Assuming django 1.7, your code could look like

class MyForm(forms.ModelForm):  

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)

        self.fields['my_date'].required = True
        self.fields['my_time'].required = True
        ...

    def clean(self):
        cleaned_data = super(MyForm, self).clean()
        # here all fields have been validated individually,
        # and so cleaned_data is fully populated
        my_date = cleaned_data.get('my_date')
        my_time = cleaned_data.get('my_time')
        if my_date and my_time:
            my_date_time = (my_date + ' ' + my_time + ':00')
            my_date_time = datetime.strptime(my_date_time, '%m/%d/%Y %H:%M:%S')
            if datetime.now() <= my_date_time:
                msg = u"Wrong Date time !"
                self.add_error('my_date', msg)
                self.add_error('my_time', msg)
        return cleaned_data

    class Meta:
        model = MyModel
        fields = ['my_date', 'my_time', ...]
like image 194
Jérôme Thiard Avatar answered Oct 15 '22 20:10

Jérôme Thiard