aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework/fields.py
diff options
context:
space:
mode:
authorTom Christie2013-03-05 17:50:28 +0000
committerTom Christie2013-03-05 17:50:28 +0000
commitc20ebe95f6707d63373d9c583e90bcbc6e021899 (patch)
tree8c51d642ef180b37f6799a45ccced9b71665fb7c /rest_framework/fields.py
parent6e7ddd579b6604d1b0d6da8e4d09762be4520e35 (diff)
parent5e5cd6f7f7357d68d5c10500ec0379e49d679202 (diff)
downloaddjango-rest-framework-c20ebe95f6707d63373d9c583e90bcbc6e021899.tar.bz2
Merge datetime formats
Diffstat (limited to 'rest_framework/fields.py')
-rw-r--r--rest_framework/fields.py151
1 files changed, 104 insertions, 47 deletions
diff --git a/rest_framework/fields.py b/rest_framework/fields.py
index 86c3a837..e65f0307 100644
--- a/rest_framework/fields.py
+++ b/rest_framework/fields.py
@@ -13,12 +13,14 @@ from django import forms
from django.forms import widgets
from django.utils.encoding import is_protected_type
from django.utils.translation import ugettext_lazy as _
-from rest_framework.compat import parse_date, parse_datetime
-from rest_framework.compat import timezone
+
+from rest_framework import ISO8601
+from rest_framework.compat import timezone, parse_date, parse_datetime, parse_time
from rest_framework.compat import BytesIO
from rest_framework.compat import six
from rest_framework.compat import smart_text
-from rest_framework.compat import parse_time
+from rest_framework.settings import api_settings
+from rest_framework.utils.dates import get_readable_date_format
def is_simple_callable(obj):
@@ -447,12 +449,16 @@ class DateField(WritableField):
form_field_class = forms.DateField
default_error_messages = {
- 'invalid': _("'%s' value has an invalid date format. It must be "
- "in YYYY-MM-DD format."),
- 'invalid_date': _("'%s' value has the correct format (YYYY-MM-DD) "
- "but it is an invalid date."),
+ 'invalid': _("Date has wrong format. Use one of these formats instead: %s"),
}
empty = None
+ input_formats = api_settings.DATE_INPUT_FORMATS
+ output_format = api_settings.DATE_OUTPUT_FORMAT
+
+ def __init__(self, input_formats=None, output_format=None, *args, **kwargs):
+ self.input_formats = input_formats if input_formats is not None else self.input_formats
+ self.output_format = output_format if output_format is not None else self.output_format
+ super(DateField, self).__init__(*args, **kwargs)
def from_native(self, value):
if value in validators.EMPTY_VALUES:
@@ -468,17 +474,34 @@ class DateField(WritableField):
if isinstance(value, datetime.date):
return value
- try:
- parsed = parse_date(value)
- if parsed is not None:
- return parsed
- except (ValueError, TypeError):
- msg = self.error_messages['invalid_date'] % value
- raise ValidationError(msg)
+ for format in self.input_formats:
+ if format.lower() == ISO8601:
+ try:
+ parsed = parse_date(value)
+ except (ValueError, TypeError):
+ pass
+ else:
+ if parsed is not None:
+ return parsed
+ else:
+ try:
+ parsed = datetime.datetime.strptime(value, format)
+ except (ValueError, TypeError):
+ pass
+ else:
+ return parsed.date()
- msg = self.error_messages['invalid'] % value
+ date_input_formats = '; '.join(self.input_formats).replace(ISO8601, 'YYYY-MM-DD')
+ msg = self.error_messages['invalid'] % get_readable_date_format(date_input_formats)
raise ValidationError(msg)
+ def to_native(self, value):
+ if isinstance(value, datetime.datetime):
+ value = value.date()
+ if self.output_format.lower() == ISO8601:
+ return value.isoformat()
+ return value.strftime(self.output_format)
+
class DateTimeField(WritableField):
type_name = 'DateTimeField'
@@ -486,15 +509,16 @@ class DateTimeField(WritableField):
form_field_class = forms.DateTimeField
default_error_messages = {
- 'invalid': _("'%s' value has an invalid format. It must be in "
- "YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format."),
- 'invalid_date': _("'%s' value has the correct format "
- "(YYYY-MM-DD) but it is an invalid date."),
- 'invalid_datetime': _("'%s' value has the correct format "
- "(YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]) "
- "but it is an invalid date/time."),
+ 'invalid': _("Datetime has wrong format. Use one of these formats instead: %s"),
}
empty = None
+ input_formats = api_settings.DATETIME_INPUT_FORMATS
+ output_format = api_settings.DATETIME_OUTPUT_FORMAT
+
+ def __init__(self, input_formats=None, output_format=None, *args, **kwargs):
+ self.input_formats = input_formats if input_formats is not None else self.input_formats
+ self.output_format = output_format if output_format is not None else self.output_format
+ super(DateTimeField, self).__init__(*args, **kwargs)
def from_native(self, value):
if value in validators.EMPTY_VALUES:
@@ -516,25 +540,32 @@ class DateTimeField(WritableField):
value = timezone.make_aware(value, default_timezone)
return value
- try:
- parsed = parse_datetime(value)
- if parsed is not None:
- return parsed
- except (ValueError, TypeError):
- msg = self.error_messages['invalid_datetime'] % value
- raise ValidationError(msg)
-
- try:
- parsed = parse_date(value)
- if parsed is not None:
- return datetime.datetime(parsed.year, parsed.month, parsed.day)
- except (ValueError, TypeError):
- msg = self.error_messages['invalid_date'] % value
- raise ValidationError(msg)
+ for format in self.input_formats:
+ if format.lower() == ISO8601:
+ try:
+ parsed = parse_datetime(value)
+ except (ValueError, TypeError):
+ pass
+ else:
+ if parsed is not None:
+ return parsed
+ else:
+ try:
+ parsed = datetime.datetime.strptime(value, format)
+ except (ValueError, TypeError):
+ pass
+ else:
+ return parsed
- msg = self.error_messages['invalid'] % value
+ datetime_input_formats = '; '.join(self.input_formats).replace(ISO8601, 'YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]')
+ msg = self.error_messages['invalid'] % get_readable_date_format(datetime_input_formats)
raise ValidationError(msg)
+ def to_native(self, value):
+ if self.output_format.lower() == ISO8601:
+ return value.isoformat()
+ return value.strftime(self.output_format)
+
class TimeField(WritableField):
type_name = 'TimeField'
@@ -542,10 +573,16 @@ class TimeField(WritableField):
form_field_class = forms.TimeField
default_error_messages = {
- 'invalid': _("'%s' value has an invalid format. It must be a valid "
- "time in the HH:MM[:ss[.uuuuuu]] format."),
+ 'invalid': _("Time has wrong format. Use one of these formats instead: %s"),
}
empty = None
+ input_formats = api_settings.TIME_INPUT_FORMATS
+ output_format = api_settings.TIME_OUTPUT_FORMAT
+
+ def __init__(self, input_formats=None, output_format=None, *args, **kwargs):
+ self.input_formats = input_formats if input_formats is not None else self.input_formats
+ self.output_format = output_format if output_format is not None else self.output_format
+ super(TimeField, self).__init__(*args, **kwargs)
def from_native(self, value):
if value in validators.EMPTY_VALUES:
@@ -554,13 +591,33 @@ class TimeField(WritableField):
if isinstance(value, datetime.time):
return value
- try:
- parsed = parse_time(value)
- assert parsed is not None
- return parsed
- except (ValueError, TypeError):
- msg = self.error_messages['invalid'] % value
- raise ValidationError(msg)
+ for format in self.input_formats:
+ if format.lower() == ISO8601:
+ try:
+ parsed = parse_time(value)
+ except (ValueError, TypeError):
+ pass
+ else:
+ if parsed is not None:
+ return parsed
+ else:
+ try:
+ parsed = datetime.datetime.strptime(value, format)
+ except (ValueError, TypeError):
+ pass
+ else:
+ return parsed.time()
+
+ time_input_formats = '; '.join(self.input_formats).replace(ISO8601, 'HH:MM[:ss[.uuuuuu]]')
+ msg = self.error_messages['invalid'] % get_readable_date_format(time_input_formats)
+ raise ValidationError(msg)
+
+ def to_native(self, value):
+ if isinstance(value, datetime.datetime):
+ value = value.time()
+ if self.output_format.lower() == ISO8601:
+ return value.isoformat()
+ return value.strftime(self.output_format)
class IntegerField(WritableField):