aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Groß2013-03-01 16:24:25 +0100
committerStephan Groß2013-03-01 16:50:18 +0100
commit9c964cf37b6936e907d250306e15c3f116591e7c (patch)
treebf78a31bfbca1ef9ae0595f7b31ce8347fc71539
parenta9d36d4726fc8eea02184b089ee6ed1d02e4c75e (diff)
downloaddjango-rest-framework-9c964cf37b6936e907d250306e15c3f116591e7c.tar.bz2
Add new ISO8601 setting + integration
-rw-r--r--rest_framework/__init__.py3
-rw-r--r--rest_framework/fields.py83
-rw-r--r--rest_framework/settings.py20
-rw-r--r--rest_framework/tests/fields.py38
4 files changed, 84 insertions, 60 deletions
diff --git a/rest_framework/__init__.py b/rest_framework/__init__.py
index 29f3d7bc..d26bb6bf 100644
--- a/rest_framework/__init__.py
+++ b/rest_framework/__init__.py
@@ -4,3 +4,6 @@ VERSION = __version__ # synonym
# Header encoding (see RFC5987)
HTTP_HEADER_ENCODING = 'iso-8859-1'
+
+# Default input and output format
+ISO8601 = 'iso-8601' \ No newline at end of file
diff --git a/rest_framework/fields.py b/rest_framework/fields.py
index 3eaa532a..c3e83c5e 100644
--- a/rest_framework/fields.py
+++ b/rest_framework/fields.py
@@ -11,9 +11,11 @@ from django.core.exceptions import ValidationError
from django.conf import settings
from django import forms
from django.forms import widgets
+from django.utils.dateparse import parse_date, parse_datetime, parse_time
from django.utils.encoding import is_protected_type
from django.utils.translation import ugettext_lazy as _
+from rest_framework import ISO8601
from rest_framework.compat import timezone
from rest_framework.compat import BytesIO
from rest_framework.compat import six
@@ -472,21 +474,30 @@ class DateField(WritableField):
return value
for format in self.input_formats:
- try:
- parsed = datetime.datetime.strptime(value, format)
- except (ValueError, TypeError):
- pass
+ if format.lower() == ISO8601:
+ try:
+ parsed = parse_date(value)
+ except (ValueError, TypeError):
+ pass
+ else:
+ if parsed is not None:
+ return parsed
else:
- return parsed.date()
+ try:
+ parsed = datetime.datetime.strptime(value, format)
+ except (ValueError, TypeError):
+ pass
+ else:
+ return parsed.date()
- date_input_formats = '; '.join(self.input_formats)
+ 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 self.output_format is not None:
- return value.strftime(self.output_format)
- return value.isoformat()
+ if self.output_format.lower() == ISO8601:
+ return value.isoformat()
+ return value.strftime(self.output_format)
class DateTimeField(WritableField):
@@ -525,21 +536,30 @@ class DateTimeField(WritableField):
return value
for format in self.input_formats:
- try:
- parsed = datetime.datetime.strptime(value, format)
- except (ValueError, TypeError):
- pass
+ if format.lower() == ISO8601:
+ try:
+ parsed = parse_datetime(value)
+ except (ValueError, TypeError):
+ pass
+ else:
+ if parsed is not None:
+ return parsed
else:
- return parsed
+ try:
+ parsed = datetime.datetime.strptime(value, format)
+ except (ValueError, TypeError):
+ pass
+ else:
+ return parsed
- datetime_input_formats = '; '.join(self.input_formats)
+ 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 is not None:
- return value.strftime(self.output_format)
- return value.isoformat()
+ if self.output_format.lower() == ISO8601:
+ return value.isoformat()
+ return value.strftime(self.output_format)
class TimeField(WritableField):
@@ -565,21 +585,30 @@ class TimeField(WritableField):
return value
for format in self.input_formats:
- try:
- parsed = datetime.datetime.strptime(value, format)
- except (ValueError, TypeError):
- pass
+ if format.lower() == ISO8601:
+ try:
+ parsed = parse_time(value)
+ except (ValueError, TypeError):
+ pass
+ else:
+ if parsed is not None:
+ return parsed
else:
- return parsed.time()
+ try:
+ parsed = datetime.datetime.strptime(value, format)
+ except (ValueError, TypeError):
+ pass
+ else:
+ return parsed.time()
- time_input_formats = '; '.join(self.input_formats)
+ 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 self.output_format is not None:
- return value.strftime(self.output_format)
- return value.isoformat()
+ if self.output_format.lower() == ISO8601:
+ return value.isoformat()
+ return value.strftime(self.output_format)
class IntegerField(WritableField):
diff --git a/rest_framework/settings.py b/rest_framework/settings.py
index 717496ea..02d751e1 100644
--- a/rest_framework/settings.py
+++ b/rest_framework/settings.py
@@ -18,8 +18,11 @@ REST framework settings, checking for user settings first, then falling
back to the defaults.
"""
from __future__ import unicode_literals
+
from django.conf import settings
from django.utils import importlib
+
+from rest_framework import ISO8601
from rest_framework.compat import six
@@ -79,24 +82,19 @@ DEFAULTS = {
# Input and output formats
'DATE_INPUT_FORMATS': (
- '%Y-%m-%d', # '1984-07-31'
+ ISO8601,
),
- 'DATE_OUTPUT_FORMAT': None,
+ 'DATE_OUTPUT_FORMAT': ISO8601,
'DATETIME_INPUT_FORMATS': (
- '%Y-%m-%d', # '1984-07-31'
- '%Y-%m-%d %H:%M', # '1984-07-31 04:31'
- '%Y-%m-%d %H:%M:%S', # '1984-07-31 04:31:59'
- '%Y-%m-%d %H:%M:%S.%f', # '1984-07-31 04:31:59.000200'
+ ISO8601,
),
- 'DATETIME_OUTPUT_FORMAT': None,
+ 'DATETIME_OUTPUT_FORMAT': ISO8601,
'TIME_INPUT_FORMATS': (
- '%H:%M', # '04:31'
- '%H:%M:%S', # '04:31:59'
- '%H:%M:%S.%f', # '04:31:59.000200'
+ ISO8601,
),
- 'TIME_OUTPUT_FORMAT': None,
+ 'TIME_OUTPUT_FORMAT': ISO8601,
}
diff --git a/rest_framework/tests/fields.py b/rest_framework/tests/fields.py
index 6630e0b2..3b84ab1c 100644
--- a/rest_framework/tests/fields.py
+++ b/rest_framework/tests/fields.py
@@ -173,30 +173,26 @@ class DateTimeFieldTest(TestCase):
Make sure from_native() accepts default iso input formats.
"""
f = serializers.DateTimeField()
- result_1 = f.from_native('1984-07-31')
- result_2 = f.from_native('1984-07-31 04:31')
- result_3 = f.from_native('1984-07-31 04:31:59')
- result_4 = f.from_native('1984-07-31 04:31:59.000200')
+ result_1 = f.from_native('1984-07-31 04:31')
+ result_2 = f.from_native('1984-07-31 04:31:59')
+ result_3 = f.from_native('1984-07-31 04:31:59.000200')
- self.assertEqual(datetime.datetime(1984, 7, 31), result_1)
- self.assertEqual(datetime.datetime(1984, 7, 31, 4, 31), result_2)
- self.assertEqual(datetime.datetime(1984, 7, 31, 4, 31, 59), result_3)
- self.assertEqual(datetime.datetime(1984, 7, 31, 4, 31, 59, 200), result_4)
+ self.assertEqual(datetime.datetime(1984, 7, 31, 4, 31), result_1)
+ self.assertEqual(datetime.datetime(1984, 7, 31, 4, 31, 59), result_2)
+ self.assertEqual(datetime.datetime(1984, 7, 31, 4, 31, 59, 200), result_3)
def test_from_native_datetime_datetime(self):
"""
Make sure from_native() accepts a datetime.datetime instance.
"""
f = serializers.DateTimeField()
- result_1 = f.from_native(datetime.datetime(1984, 7, 31))
- result_2 = f.from_native(datetime.datetime(1984, 7, 31, 4, 31))
- result_3 = f.from_native(datetime.datetime(1984, 7, 31, 4, 31, 59))
- result_4 = f.from_native(datetime.datetime(1984, 7, 31, 4, 31, 59, 200))
+ result_1 = f.from_native(datetime.datetime(1984, 7, 31, 4, 31))
+ result_2 = f.from_native(datetime.datetime(1984, 7, 31, 4, 31, 59))
+ result_3 = f.from_native(datetime.datetime(1984, 7, 31, 4, 31, 59, 200))
- self.assertEqual(result_1, datetime.datetime(1984, 7, 31))
- self.assertEqual(result_2, datetime.datetime(1984, 7, 31, 4, 31))
- self.assertEqual(result_3, datetime.datetime(1984, 7, 31, 4, 31, 59))
- self.assertEqual(result_4, datetime.datetime(1984, 7, 31, 4, 31, 59, 200))
+ self.assertEqual(result_1, datetime.datetime(1984, 7, 31, 4, 31))
+ self.assertEqual(result_2, datetime.datetime(1984, 7, 31, 4, 31, 59))
+ self.assertEqual(result_3, datetime.datetime(1984, 7, 31, 4, 31, 59, 200))
def test_from_native_custom_format(self):
"""
@@ -239,8 +235,7 @@ class DateTimeFieldTest(TestCase):
f.from_native('04:61:59')
except validators.ValidationError as e:
self.assertEqual(e.messages, ["Datetime has wrong format. Use one of these formats instead: "
- "YYYY-MM-DD; YYYY-MM-DD HH:MM; YYYY-MM-DD HH:MM:SS; "
- "YYYY-MM-DD HH:MM:SS.uuuuuu"])
+ "YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]"])
else:
self.fail("ValidationError was not properly raised")
@@ -254,8 +249,7 @@ class DateTimeFieldTest(TestCase):
f.from_native('04 -- 31')
except validators.ValidationError as e:
self.assertEqual(e.messages, ["Datetime has wrong format. Use one of these formats instead: "
- "YYYY-MM-DD; YYYY-MM-DD HH:MM; YYYY-MM-DD HH:MM:SS; "
- "YYYY-MM-DD HH:MM:SS.uuuuuu"])
+ "YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]"])
else:
self.fail("ValidationError was not properly raised")
@@ -364,7 +358,7 @@ class TimeFieldTest(TestCase):
f.from_native('04:61:59')
except validators.ValidationError as e:
self.assertEqual(e.messages, ["Time has wrong format. Use one of these formats instead: "
- "HH:MM; HH:MM:SS; HH:MM:SS.uuuuuu"])
+ "HH:MM[:ss[.uuuuuu]]"])
else:
self.fail("ValidationError was not properly raised")
@@ -378,7 +372,7 @@ class TimeFieldTest(TestCase):
f.from_native('04 -- 31')
except validators.ValidationError as e:
self.assertEqual(e.messages, ["Time has wrong format. Use one of these formats instead: "
- "HH:MM; HH:MM:SS; HH:MM:SS.uuuuuu"])
+ "HH:MM[:ss[.uuuuuu]]"])
else:
self.fail("ValidationError was not properly raised")