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)