1 | """
|
---|
2 | Extra Field Classes
|
---|
3 | """
|
---|
4 |
|
---|
5 | from fields import Field, ValidationError, gettext, EMPTY_VALUES
|
---|
6 | import datetime
|
---|
7 |
|
---|
8 | ### HumanDateTimeField ###
|
---|
9 | from parsedatetime import parsedatetime
|
---|
10 |
|
---|
11 | #The constructor compiles a bunch of regexs, might as well do it only once.
|
---|
12 | parse_calendar = parsedatetime.Calendar()
|
---|
13 |
|
---|
14 | def parse_date_time(string):
|
---|
15 | tup, flag = parse_calendar.parse(string)
|
---|
16 | if (flag == 0): # The string could not be parsed
|
---|
17 | raise ValueError, "Unable to parse date/time."
|
---|
18 | if (flag == 1): # This was just a date
|
---|
19 | value = datetime.datetime(*(tup[:3]))
|
---|
20 | else:
|
---|
21 | value = datetime.datetime(*(tup[:6]))
|
---|
22 | return value
|
---|
23 |
|
---|
24 | class HumanDateTimeField(Field):
|
---|
25 | """
|
---|
26 | Uses the parsedatetime library to clean the value thereby allowing
|
---|
27 | many different date-formats, including human readable strings like,
|
---|
28 | "tomorrow" and "thursday at 10 pm".
|
---|
29 |
|
---|
30 | parsedatetime library: http://cheeseshop.python.org/pypi/parsedatetime/
|
---|
31 | """
|
---|
32 |
|
---|
33 | def clean(self, value):
|
---|
34 | """
|
---|
35 | Validates that the input can be converted to a datetime. Returns a Python
|
---|
36 | datetime.datetime object.
|
---|
37 | """
|
---|
38 |
|
---|
39 | Field.clean(self, value)
|
---|
40 | if value in EMPTY_VALUES:
|
---|
41 | return None
|
---|
42 | if isinstance(value, datetime.datetime):
|
---|
43 | return value
|
---|
44 | if isinstance(value, datetime.date):
|
---|
45 | return datetime.datetime(value.year, value.month, value.day)
|
---|
46 | try:
|
---|
47 | return parse_date_time(value)
|
---|
48 | except ValueError:
|
---|
49 | pass
|
---|
50 | raise ValidationError(
|
---|
51 | gettext(u'Enter a valid date/time, like "today", "next tuesday at 2 am", "2006-10-28", or "10/24/99"'))
|
---|