Natural language date/time form fields

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from dateutil import parser

class ParseDateTimeField(forms.Field):
    """ DateTime field that accepts natural-language input

    Uses the DateUtil module to parse input.

    """
    def clean(self, value):
        super(ParseDateTimeField, self).clean(value)
        if value in (None, ''):
            return None
        if isinstance(value, datetime):
            return value
        try:
            return parser.parse(value)
        except ValueError:
            raise ValidationError(u'Enter a valid date and time')


class ParseDateField(forms.Field):
    """ Date field that accepts natural-language input

    Uses the DateUtil module to parse input.

    """
    def clean(self, value):
        super(ParseDateField, self).clean(value)
        if value in (None, ''):
            return None
        if isinstance(value, datetime):
            return value
        try:
            return parser.parse(value).date()
        except ValueError:
            raise ValidationError(u'Enter a valid date')

def parsefield_callback(field, **kwargs):
    """ Replace standard DateField and DateTimeField with parsing variants """
    if isinstance(field, models.DateTimeField):
        kwargs.update({'form_class': ParseDateTimeField})
    elif isinstance(field, models.DateField):
        kwargs.update({'form_class': ParseDateField})
    return field.formfield(**kwargs)

MyForm = forms_for_model(MyModel, formfield_callback=parsefield_callback)

More like this

  1. FuzzyDateTimeField by japerk 5 years ago
  2. timeto template filter by japerk 5 years ago
  3. isoutc template filter by japerk 5 years ago
  4. Parse datetime model field to string by jzelez 3 years, 9 months ago
  5. Datetime widget by pigletto 6 years, 7 months ago

Comments

gsf0 (on December 12, 2008):

Also need "from datetime import datetime". Thanks for the example!

#

gsf0 (on December 12, 2008):

Oh, also, with the SplitDateTimeWidget I needed to change it to parser.parse(' '.join(value)).

#

gsf0 (on December 12, 2008):

Or, in keeping with the code in django.forms.fields, I could include:

if isinstance(value, list):
    # Input comes from a SplitDateTimeWidget, for example. So, it's two
    # components: date and time.
    if len(value) != 2:
        raise ValidationError(self.error_messages['invalid'])
    value = '%s %s' % tuple(value)

#

(Forgotten your password?)