Add drf settings + output format + testcases

This commit is contained in:
Stephan Groß 2013-03-01 13:16:00 +01:00
parent 36d5b24b76
commit 876a58e8bf
6 changed files with 322 additions and 285 deletions

View File

@ -13,12 +13,12 @@ from django import forms
from django.forms import widgets from django.forms import widgets
from django.utils.encoding import is_protected_type from django.utils.encoding import is_protected_type
from django.utils.translation import ugettext_lazy as _ 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.compat import timezone
from rest_framework.compat import BytesIO from rest_framework.compat import BytesIO
from rest_framework.compat import six from rest_framework.compat import six
from rest_framework.compat import smart_text 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 from rest_framework.utils.dates import get_readable_date_format
@ -453,7 +453,8 @@ class DateField(WritableField):
empty = None empty = None
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.format = kwargs.pop('format', settings.DATE_INPUT_FORMATS) self.input_formats = kwargs.pop('input_formats', api_settings.DATE_INPUT_FORMATS)
self.output_format = kwargs.pop('output_format', api_settings.DATE_OUTPUT_FORMAT)
super(DateField, self).__init__(*args, **kwargs) super(DateField, self).__init__(*args, **kwargs)
def from_native(self, value): def from_native(self, value):
@ -470,7 +471,7 @@ class DateField(WritableField):
if isinstance(value, datetime.date): if isinstance(value, datetime.date):
return value return value
for format in self.format: for format in self.input_formats:
try: try:
parsed = datetime.datetime.strptime(value, format) parsed = datetime.datetime.strptime(value, format)
except (ValueError, TypeError): except (ValueError, TypeError):
@ -478,10 +479,15 @@ class DateField(WritableField):
else: else:
return parsed.date() return parsed.date()
date_input_formats = '; '.join(self.format) date_input_formats = '; '.join(self.input_formats)
msg = self.error_messages['invalid'] % get_readable_date_format(date_input_formats) msg = self.error_messages['invalid'] % get_readable_date_format(date_input_formats)
raise ValidationError(msg) raise ValidationError(msg)
def to_native(self, value):
if self.output_format is not None:
return value.strftime(self.output_format)
return value.isoformat()
class DateTimeField(WritableField): class DateTimeField(WritableField):
type_name = 'DateTimeField' type_name = 'DateTimeField'
@ -494,7 +500,8 @@ class DateTimeField(WritableField):
empty = None empty = None
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.format = kwargs.pop('format', settings.DATETIME_INPUT_FORMATS) self.input_formats = kwargs.pop('input_formats', api_settings.DATETIME_INPUT_FORMATS)
self.output_format = kwargs.pop('output_format', api_settings.DATETIME_OUTPUT_FORMAT)
super(DateTimeField, self).__init__(*args, **kwargs) super(DateTimeField, self).__init__(*args, **kwargs)
def from_native(self, value): def from_native(self, value):
@ -517,7 +524,7 @@ class DateTimeField(WritableField):
value = timezone.make_aware(value, default_timezone) value = timezone.make_aware(value, default_timezone)
return value return value
for format in self.format: for format in self.input_formats:
try: try:
parsed = datetime.datetime.strptime(value, format) parsed = datetime.datetime.strptime(value, format)
except (ValueError, TypeError): except (ValueError, TypeError):
@ -525,10 +532,15 @@ class DateTimeField(WritableField):
else: else:
return parsed return parsed
datetime_input_formats = '; '.join(self.format) datetime_input_formats = '; '.join(self.input_formats)
msg = self.error_messages['invalid'] % get_readable_date_format(datetime_input_formats) msg = self.error_messages['invalid'] % get_readable_date_format(datetime_input_formats)
raise ValidationError(msg) raise ValidationError(msg)
def to_native(self, value):
if self.output_format is not None:
return value.strftime(self.output_format)
return value.isoformat()
class TimeField(WritableField): class TimeField(WritableField):
type_name = 'TimeField' type_name = 'TimeField'
@ -541,7 +553,8 @@ class TimeField(WritableField):
empty = None empty = None
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.format = kwargs.pop('format', settings.TIME_INPUT_FORMATS) self.input_formats = kwargs.pop('input_formats', api_settings.TIME_INPUT_FORMATS)
self.output_format = kwargs.pop('output_format', api_settings.TIME_OUTPUT_FORMAT)
super(TimeField, self).__init__(*args, **kwargs) super(TimeField, self).__init__(*args, **kwargs)
def from_native(self, value): def from_native(self, value):
@ -551,7 +564,7 @@ class TimeField(WritableField):
if isinstance(value, datetime.time): if isinstance(value, datetime.time):
return value return value
for format in self.format: for format in self.input_formats:
try: try:
parsed = datetime.datetime.strptime(value, format) parsed = datetime.datetime.strptime(value, format)
except (ValueError, TypeError): except (ValueError, TypeError):
@ -559,10 +572,15 @@ class TimeField(WritableField):
else: else:
return parsed.time() return parsed.time()
time_input_formats = '; '.join(self.format) time_input_formats = '; '.join(self.input_formats)
msg = self.error_messages['invalid'] % get_readable_date_format(time_input_formats) msg = self.error_messages['invalid'] % get_readable_date_format(time_input_formats)
raise ValidationError(msg) raise ValidationError(msg)
def to_native(self, value):
if self.output_format is not None:
return value.strftime(self.output_format)
return value.isoformat()
class IntegerField(WritableField): class IntegerField(WritableField):
type_name = 'IntegerField' type_name = 'IntegerField'

View File

@ -76,6 +76,27 @@ DEFAULTS = {
'URL_FORMAT_OVERRIDE': 'format', 'URL_FORMAT_OVERRIDE': 'format',
'FORMAT_SUFFIX_KWARG': 'format', 'FORMAT_SUFFIX_KWARG': 'format',
# Input and output formats
'DATE_INPUT_FORMATS': (
'%Y-%m-%d', # '1984-07-31'
),
'DATE_OUTPUT_FORMAT': None,
'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'
),
'DATETIME_OUTPUT_FORMAT': None,
'TIME_INPUT_FORMATS': (
'%H:%M', # '04:31'
'%H:%M:%S', # '04:31:59'
'%H:%M:%S.%f', # '04:31:59.000200'
),
'TIME_OUTPUT_FORMAT': None,
} }

View File

@ -4,11 +4,9 @@ General serializer field tests.
from __future__ import unicode_literals from __future__ import unicode_literals
import datetime import datetime
import django
from django.db import models from django.db import models
from django.test import TestCase from django.test import TestCase
from django.core import validators from django.core import validators
from django.utils import unittest
from rest_framework import serializers from rest_framework import serializers
@ -22,21 +20,6 @@ class CharPrimaryKeyModel(models.Model):
id = models.CharField(max_length=20, primary_key=True) id = models.CharField(max_length=20, primary_key=True)
class DateObject(object):
def __init__(self, date):
self.date = date
class DateTimeObject(object):
def __init__(self, date_time):
self.date_time = date_time
class TimeObject(object):
def __init__(self, time):
self.time = time
class TimestampedModelSerializer(serializers.ModelSerializer): class TimestampedModelSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = TimestampedModel model = TimestampedModel
@ -47,66 +30,6 @@ class CharPrimaryKeyModelSerializer(serializers.ModelSerializer):
model = CharPrimaryKeyModel model = CharPrimaryKeyModel
class DateObjectSerializer(serializers.Serializer):
date = serializers.DateField()
def restore_object(self, attrs, instance=None):
if instance is not None:
instance.date = attrs['date']
return instance
return DateObject(**attrs)
class DateObjectCustomFormatSerializer(serializers.Serializer):
date = serializers.DateField(format=("%Y", "%Y -- %m"))
def restore_object(self, attrs, instance=None):
if instance is not None:
instance.date = attrs['date']
return instance
return DateObject(**attrs)
class DateTimeObjectSerializer(serializers.Serializer):
date_time = serializers.DateTimeField()
def restore_object(self, attrs, instance=None):
if instance is not None:
instance.date_time = attrs['date_time']
return instance
return DateTimeObject(**attrs)
class DateTimeObjectCustomFormatSerializer(serializers.Serializer):
date_time = serializers.DateTimeField(format=("%Y", "%Y %H:%M"))
def restore_object(self, attrs, instance=None):
if instance is not None:
instance.date_time = attrs['date_time']
return instance
return DateTimeObject(**attrs)
class TimeObjectSerializer(serializers.Serializer):
time = serializers.TimeField()
def restore_object(self, attrs, instance=None):
if instance is not None:
instance.time = attrs['time']
return instance
return TimeObject(**attrs)
class TimeObjectCustomFormatSerializer(serializers.Serializer):
time = serializers.TimeField(format=("%H -- %M", "%H%M%S"))
def restore_object(self, attrs, instance=None):
if instance is not None:
instance.time = attrs['time']
return instance
return TimeObject(**attrs)
class TimeFieldModel(models.Model): class TimeFieldModel(models.Model):
clock = models.TimeField() clock = models.TimeField()
@ -140,273 +63,347 @@ class BasicFieldTests(TestCase):
class DateFieldTest(TestCase): class DateFieldTest(TestCase):
def test_valid_default_date_input_formats(self): """
serializer = DateObjectSerializer(data={'date': '1984-07-31'}) Tests for the DateFieldTest from_native() and to_native() behavior
self.assertTrue(serializer.is_valid()) """
serializer = DateObjectSerializer(data={'date': '07/31/1984'}) def test_from_native_string(self):
self.assertTrue(serializer.is_valid()) """
Make sure from_native() accepts default iso input formats.
serializer = DateObjectSerializer(data={'date': '07/31/84'}) """
self.assertTrue(serializer.is_valid())
serializer = DateObjectSerializer(data={'date': 'Jul 31 1984'})
self.assertTrue(serializer.is_valid())
serializer = DateObjectSerializer(data={'date': 'Jul 31, 1984'})
self.assertTrue(serializer.is_valid())
serializer = DateObjectSerializer(data={'date': '31 Jul 1984'})
self.assertTrue(serializer.is_valid())
serializer = DateObjectSerializer(data={'date': '31 Jul 1984'})
self.assertTrue(serializer.is_valid())
serializer = DateObjectSerializer(data={'date': 'July 31 1984'})
self.assertTrue(serializer.is_valid())
serializer = DateObjectSerializer(data={'date': 'July 31, 1984'})
self.assertTrue(serializer.is_valid())
serializer = DateObjectSerializer(data={'date': '31 July 1984'})
self.assertTrue(serializer.is_valid())
serializer = DateObjectSerializer(data={'date': '31 July, 1984'})
self.assertTrue(serializer.is_valid())
def test_valid_custom_date_input_formats(self):
serializer = DateObjectCustomFormatSerializer(data={'date': '1984'})
self.assertTrue(serializer.is_valid())
serializer = DateObjectCustomFormatSerializer(data={'date': '1984 -- 07'})
self.assertTrue(serializer.is_valid())
def test_wrong_default_date_input_format(self):
serializer = DateObjectSerializer(data={'date': 'something wrong'})
self.assertFalse(serializer.is_valid())
self.assertEquals(serializer.errors, {'date': ['Date has wrong format. Use one of these formats instead: '
'YYYY-MM-DD; MM/DD/YYYY; MM/DD/YY; [Jan through Dec] DD YYYY; '
'[Jan through Dec] DD, YYYY; DD [Jan through Dec] YYYY; '
'DD [Jan through Dec], YYYY; [January through December] DD YYYY; '
'[January through December] DD, YYYY; DD [January through December] YYYY; '
'DD [January through December], YYYY']})
def test_wrong_custom_date_input_format(self):
serializer = DateObjectCustomFormatSerializer(data={'date': '07/31/1984'})
self.assertFalse(serializer.is_valid())
self.assertEquals(serializer.errors, {'date': ['Date has wrong format. Use one of these formats instead: YYYY; YYYY -- MM']})
def test_from_native(self):
f = serializers.DateField() f = serializers.DateField()
result = f.from_native('1984-07-31') result_1 = f.from_native('1984-07-31')
self.assertEqual(datetime.date(1984, 7, 31), result) self.assertEqual(datetime.date(1984, 7, 31), result_1)
def test_from_native_datetime_date(self): def test_from_native_datetime_date(self):
""" """
Make sure from_native() accepts a datetime.date instance. Make sure from_native() accepts a datetime.date instance.
""" """
f = serializers.DateField() f = serializers.DateField()
result = f.from_native(datetime.date(1984, 7, 31)) result_1 = f.from_native(datetime.date(1984, 7, 31))
self.assertEqual(result, datetime.date(1984, 7, 31)) self.assertEqual(result_1, datetime.date(1984, 7, 31))
def test_from_native_custom_format(self):
"""
Make sure from_native() accepts custom input formats.
"""
f = serializers.DateField(input_formats=['%Y -- %d'])
result = f.from_native('1984 -- 31')
self.assertEqual(datetime.date(1984, 1, 31), result)
def test_from_native_invalid_default_on_custom_format(self):
"""
Make sure from_native() don't accept default formats if custom format is preset
"""
f = serializers.DateField(input_formats=['%Y -- %d'])
try:
f.from_native('1984-07-31')
except validators.ValidationError as e:
self.assertEqual(e.messages, ["Date has wrong format. Use one of these formats instead: YYYY -- DD"])
else:
self.fail("ValidationError was not properly raised")
def test_from_native_empty(self): def test_from_native_empty(self):
"""
Make sure from_native() returns None on empty param.
"""
f = serializers.DateField() f = serializers.DateField()
result = f.from_native('') result = f.from_native('')
self.assertEqual(result, None) self.assertEqual(result, None)
def test_from_native_invalid_date(self): def test_from_native_invalid_date(self):
"""
Make sure from_native() raises a ValidationError on passing an invalid date.
"""
f = serializers.DateField() f = serializers.DateField()
try: try:
f.from_native('1984-42-31') f.from_native('1984-13-31')
except validators.ValidationError as e: except validators.ValidationError as e:
self.assertEqual(e.messages, ['Date has wrong format. Use one of these formats instead: ' self.assertEqual(e.messages, ["Date has wrong format. Use one of these formats instead: YYYY-MM-DD"])
'YYYY-MM-DD; MM/DD/YYYY; MM/DD/YY; [Jan through Dec] DD YYYY; '
'[Jan through Dec] DD, YYYY; DD [Jan through Dec] YYYY; '
'DD [Jan through Dec], YYYY; [January through December] DD YYYY; '
'[January through December] DD, YYYY; DD [January through December] YYYY; '
'DD [January through December], YYYY'])
else: else:
self.fail("ValidationError was not properly raised") self.fail("ValidationError was not properly raised")
def test_from_native_invalid_format(self):
"""
Make sure from_native() raises a ValidationError on passing an invalid format.
"""
f = serializers.DateField()
try:
f.from_native('1984 -- 31')
except validators.ValidationError as e:
self.assertEqual(e.messages, ["Date has wrong format. Use one of these formats instead: YYYY-MM-DD"])
else:
self.fail("ValidationError was not properly raised")
def test_to_native(self):
"""
Make sure to_native() returns isoformat as default.
"""
f = serializers.DateField()
result_1 = f.to_native(datetime.date(1984, 7, 31))
self.assertEqual('1984-07-31', result_1)
def test_to_native_custom_format(self):
"""
Make sure to_native() returns correct custom format.
"""
f = serializers.DateField(output_format="%Y - %m.%d")
result_1 = f.to_native(datetime.date(1984, 7, 31))
self.assertEqual('1984 - 07.31', result_1)
class DateTimeFieldTest(TestCase): class DateTimeFieldTest(TestCase):
def test_valid_default_date_time_input_formats(self): """
serializer = DateTimeObjectSerializer(data={'date_time': '1984-07-31 04:31:59'}) Tests for the DateTimeField from_native() and to_native() behavior
self.assertTrue(serializer.is_valid()) """
serializer = DateTimeObjectSerializer(data={'date_time': '1984-07-31 04:31'}) def test_from_native_string(self):
self.assertTrue(serializer.is_valid()) """
Make sure from_native() accepts default iso input formats.
serializer = DateTimeObjectSerializer(data={'date_time': '1984-07-31'}) """
self.assertTrue(serializer.is_valid())
serializer = DateTimeObjectSerializer(data={'date_time': '07/31/1984 04:31:59'})
self.assertTrue(serializer.is_valid())
serializer = DateTimeObjectSerializer(data={'date_time': '07/31/1984 04:31'})
self.assertTrue(serializer.is_valid())
serializer = DateTimeObjectSerializer(data={'date_time': '07/31/1984'})
self.assertTrue(serializer.is_valid())
serializer = DateTimeObjectSerializer(data={'date_time': '07/31/84 04:31:59'})
self.assertTrue(serializer.is_valid())
serializer = DateTimeObjectSerializer(data={'date_time': '07/31/84 04:31'})
self.assertTrue(serializer.is_valid())
serializer = DateTimeObjectSerializer(data={'date_time': '07/31/84'})
self.assertTrue(serializer.is_valid())
@unittest.skipUnless(django.VERSION >= (1, 4), "django < 1.4 don't have microseconds in default settings")
def test_valid_default_date_time_input_formats_for_django_gte_1_4(self):
serializer = DateTimeObjectSerializer(data={'date_time': '1984-07-31 04:31:59.123456'})
self.assertTrue(serializer.is_valid())
serializer = DateTimeObjectSerializer(data={'date_time': '07/31/1984 04:31:59.123456'})
self.assertTrue(serializer.is_valid())
serializer = DateTimeObjectSerializer(data={'date_time': '07/31/84 04:31:59.123456'})
self.assertTrue(serializer.is_valid())
def test_valid_custom_date_time_input_formats(self):
serializer = DateTimeObjectCustomFormatSerializer(data={'date_time': '1984'})
self.assertTrue(serializer.is_valid())
serializer = DateTimeObjectCustomFormatSerializer(data={'date_time': '1984 04:31'})
self.assertTrue(serializer.is_valid())
@unittest.skipUnless(django.VERSION >= (1, 4), "django < 1.4 don't have microseconds in default settings")
def test_wrong_default_date_time_input_format_for_django_gte_1_4(self):
serializer = DateTimeObjectSerializer(data={'date_time': 'something wrong'})
self.assertFalse(serializer.is_valid())
self.assertEquals(serializer.errors, {'date_time': ['Datetime has wrong format. Use one of these formats instead: '
'YYYY-MM-DD HH:MM:SS; YYYY-MM-DD HH:MM:SS.uuuuuu; YYYY-MM-DD HH:MM; '
'YYYY-MM-DD; MM/DD/YYYY HH:MM:SS; MM/DD/YYYY HH:MM:SS.uuuuuu; '
'MM/DD/YYYY HH:MM; MM/DD/YYYY; MM/DD/YY HH:MM:SS; '
'MM/DD/YY HH:MM:SS.uuuuuu; MM/DD/YY HH:MM; MM/DD/YY']})
@unittest.skipUnless(django.VERSION < (1, 4), "django >= 1.4 have microseconds in default settings")
def test_wrong_default_date_time_input_format_for_django_lt_1_4(self):
serializer = DateTimeObjectSerializer(data={'date_time': 'something wrong'})
self.assertFalse(serializer.is_valid())
self.assertEquals(serializer.errors, {'date_time': ['Datetime has wrong format. Use one of these formats instead: '
'YYYY-MM-DD HH:MM:SS; YYYY-MM-DD HH:MM; YYYY-MM-DD; '
'MM/DD/YYYY HH:MM:SS; MM/DD/YYYY HH:MM; MM/DD/YYYY; '
'MM/DD/YY HH:MM:SS; MM/DD/YY HH:MM; MM/DD/YY']})
def test_wrong_custom_date_time_input_format(self):
serializer = DateTimeObjectCustomFormatSerializer(data={'date_time': '07/31/84 04:31'})
self.assertFalse(serializer.is_valid())
self.assertEquals(serializer.errors, {'date_time': ['Datetime has wrong format. Use one of these formats instead: YYYY; YYYY HH:MM']})
def test_from_native(self):
f = serializers.DateTimeField() f = serializers.DateTimeField()
result = f.from_native('1984-07-31 04:31') 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')
self.assertEqual(datetime.datetime(1984, 7, 31, 4, 31), result) 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)
def test_from_native_datetime_datetime(self): def test_from_native_datetime_datetime(self):
""" """
Make sure from_native() accepts a datetime.date instance. Make sure from_native() accepts a datetime.datetime instance.
""" """
f = serializers.DateTimeField() f = serializers.DateTimeField()
result = f.from_native(datetime.datetime(1984, 7, 31)) 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))
self.assertEqual(result, datetime.datetime(1984, 7, 31)) 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))
def test_from_native_custom_format(self):
"""
Make sure from_native() accepts custom input formats.
"""
f = serializers.DateTimeField(input_formats=['%Y -- %H:%M'])
result = f.from_native('1984 -- 04:59')
self.assertEqual(datetime.datetime(1984, 1, 1, 4, 59), result)
def test_from_native_invalid_default_on_custom_format(self):
"""
Make sure from_native() don't accept default formats if custom format is preset
"""
f = serializers.DateTimeField(input_formats=['%Y -- %H:%M'])
try:
f.from_native('1984-07-31 04:31:59')
except validators.ValidationError as e:
self.assertEqual(e.messages, ["Datetime has wrong format. Use one of these formats instead: YYYY -- HH:MM"])
else:
self.fail("ValidationError was not properly raised")
def test_from_native_empty(self): def test_from_native_empty(self):
"""
Make sure from_native() returns None on empty param.
"""
f = serializers.DateTimeField() f = serializers.DateTimeField()
result = f.from_native('') result = f.from_native('')
self.assertEqual(result, None) self.assertEqual(result, None)
@unittest.skipUnless(django.VERSION >= (1, 4), "django < 1.4 don't have microseconds in default settings") def test_from_native_invalid_datetime(self):
def test_from_native_invalid_datetime_for_django_gte_1_4(self): """
Make sure from_native() raises a ValidationError on passing an invalid datetime.
"""
f = serializers.DateTimeField() f = serializers.DateTimeField()
try: try:
f.from_native('1984-42-31 04:31') f.from_native('04:61:59')
except validators.ValidationError as e: except validators.ValidationError as e:
self.assertEqual(e.messages, ['Datetime has wrong format. Use one of these formats instead: ' self.assertEqual(e.messages, ["Datetime has wrong format. Use one of these formats instead: "
'YYYY-MM-DD HH:MM:SS; YYYY-MM-DD HH:MM:SS.uuuuuu; YYYY-MM-DD HH:MM; ' "YYYY-MM-DD; YYYY-MM-DD HH:MM; YYYY-MM-DD HH:MM:SS; "
'YYYY-MM-DD; MM/DD/YYYY HH:MM:SS; MM/DD/YYYY HH:MM:SS.uuuuuu; ' "YYYY-MM-DD HH:MM:SS.uuuuuu"])
'MM/DD/YYYY HH:MM; MM/DD/YYYY; MM/DD/YY HH:MM:SS; '
'MM/DD/YY HH:MM:SS.uuuuuu; MM/DD/YY HH:MM; MM/DD/YY'])
else: else:
self.fail("ValidationError was not properly raised") self.fail("ValidationError was not properly raised")
@unittest.skipUnless(django.VERSION < (1, 4), "django >= 1.4 have microseconds in default settings") def test_from_native_invalid_format(self):
def test_from_native_invalid_datetime_for_django_lt_1_4(self): """
Make sure from_native() raises a ValidationError on passing an invalid format.
"""
f = serializers.DateTimeField() f = serializers.DateTimeField()
try: try:
f.from_native('1984-42-31 04:31') f.from_native('04 -- 31')
except validators.ValidationError as e: except validators.ValidationError as e:
self.assertEqual(e.messages, ['Datetime has wrong format. Use one of these formats instead: ' self.assertEqual(e.messages, ["Datetime has wrong format. Use one of these formats instead: "
'YYYY-MM-DD HH:MM:SS; YYYY-MM-DD HH:MM; YYYY-MM-DD; ' "YYYY-MM-DD; YYYY-MM-DD HH:MM; YYYY-MM-DD HH:MM:SS; "
'MM/DD/YYYY HH:MM:SS; MM/DD/YYYY HH:MM; MM/DD/YYYY; ' "YYYY-MM-DD HH:MM:SS.uuuuuu"])
'MM/DD/YY HH:MM:SS; MM/DD/YY HH:MM; MM/DD/YY'])
else: else:
self.fail("ValidationError was not properly raised") self.fail("ValidationError was not properly raised")
def test_to_native(self):
"""
Make sure to_native() returns isoformat as default.
"""
f = serializers.DateTimeField()
result_1 = f.to_native(datetime.datetime(1984, 7, 31))
result_2 = f.to_native(datetime.datetime(1984, 7, 31, 4, 31))
result_3 = f.to_native(datetime.datetime(1984, 7, 31, 4, 31, 59))
result_4 = f.to_native(datetime.datetime(1984, 7, 31, 4, 31, 59, 200))
self.assertEqual('1984-07-31T00:00:00', result_1)
self.assertEqual('1984-07-31T04:31:00', result_2)
self.assertEqual('1984-07-31T04:31:59', result_3)
self.assertEqual('1984-07-31T04:31:59.000200', result_4)
def test_to_native_custom_format(self):
"""
Make sure to_native() returns correct custom format.
"""
f = serializers.DateTimeField(output_format="%Y - %H:%M")
result_1 = f.to_native(datetime.datetime(1984, 7, 31))
result_2 = f.to_native(datetime.datetime(1984, 7, 31, 4, 31))
result_3 = f.to_native(datetime.datetime(1984, 7, 31, 4, 31, 59))
result_4 = f.to_native(datetime.datetime(1984, 7, 31, 4, 31, 59, 200))
self.assertEqual('1984 - 00:00', result_1)
self.assertEqual('1984 - 04:31', result_2)
self.assertEqual('1984 - 04:31', result_3)
self.assertEqual('1984 - 04:31', result_4)
class TimeFieldTest(TestCase): class TimeFieldTest(TestCase):
def test_valid_default_time_input_formats(self): """
serializer = TimeObjectSerializer(data={'time': '04:31'}) Tests for the TimeField from_native() and to_native() behavior
self.assertTrue(serializer.is_valid()) """
serializer = TimeObjectSerializer(data={'time': '04:31:59'}) def test_from_native_string(self):
self.assertTrue(serializer.is_valid()) """
Make sure from_native() accepts default iso input formats.
def test_valid_custom_time_input_formats(self): """
serializer = TimeObjectCustomFormatSerializer(data={'time': '04 -- 31'})
self.assertTrue(serializer.is_valid())
serializer = TimeObjectCustomFormatSerializer(data={'time': '043159'})
self.assertTrue(serializer.is_valid())
def test_wrong_default_time_input_format(self):
serializer = TimeObjectSerializer(data={'time': 'something wrong'})
self.assertFalse(serializer.is_valid())
self.assertEquals(serializer.errors, {'time': ['Time has wrong format. Use one of these formats instead: HH:MM:SS; HH:MM']})
def test_wrong_custom_time_input_format(self):
serializer = TimeObjectCustomFormatSerializer(data={'time': '04:31'})
self.assertFalse(serializer.is_valid())
self.assertEquals(serializer.errors, {'time': ['Time has wrong format. Use one of these formats instead: HH -- MM; HHMMSS']})
def test_from_native(self):
f = serializers.TimeField() f = serializers.TimeField()
result = f.from_native('12:34:56') result_1 = f.from_native('04:31')
result_2 = f.from_native('04:31:59')
result_3 = f.from_native('04:31:59.000200')
self.assertEqual(datetime.time(12, 34, 56), result) self.assertEqual(datetime.time(4, 31), result_1)
self.assertEqual(datetime.time(4, 31, 59), result_2)
self.assertEqual(datetime.time(4, 31, 59, 200), result_3)
def test_from_native_datetime_time(self): def test_from_native_datetime_time(self):
""" """
Make sure from_native() accepts a datetime.time instance. Make sure from_native() accepts a datetime.time instance.
""" """
f = serializers.TimeField() f = serializers.TimeField()
result = f.from_native(datetime.time(12, 34, 56)) result_1 = f.from_native(datetime.time(4, 31))
result_2 = f.from_native(datetime.time(4, 31, 59))
result_3 = f.from_native(datetime.time(4, 31, 59, 200))
self.assertEqual(result, datetime.time(12, 34, 56)) self.assertEqual(result_1, datetime.time(4, 31))
self.assertEqual(result_2, datetime.time(4, 31, 59))
self.assertEqual(result_3, datetime.time(4, 31, 59, 200))
def test_from_native_custom_format(self):
"""
Make sure from_native() accepts custom input formats.
"""
f = serializers.TimeField(input_formats=['%H -- %M'])
result = f.from_native('04 -- 31')
self.assertEqual(datetime.time(4, 31), result)
def test_from_native_invalid_default_on_custom_format(self):
"""
Make sure from_native() don't accept default formats if custom format is preset
"""
f = serializers.TimeField(input_formats=['%H -- %M'])
try:
f.from_native('04:31:59')
except validators.ValidationError as e:
self.assertEqual(e.messages, ["Time has wrong format. Use one of these formats instead: HH -- MM"])
else:
self.fail("ValidationError was not properly raised")
def test_from_native_empty(self): def test_from_native_empty(self):
"""
Make sure from_native() returns None on empty param.
"""
f = serializers.TimeField() f = serializers.TimeField()
result = f.from_native('') result = f.from_native('')
self.assertEqual(result, None) self.assertEqual(result, None)
def test_from_native_invalid_time(self): def test_from_native_invalid_time(self):
"""
Make sure from_native() raises a ValidationError on passing an invalid time.
"""
f = serializers.TimeField() f = serializers.TimeField()
try: try:
f.from_native('12:69:12') f.from_native('04:61:59')
except validators.ValidationError as e: except validators.ValidationError as e:
self.assertEqual(e.messages, ["Time has wrong format. Use one of these formats instead: HH:MM:SS; HH:MM"]) self.assertEqual(e.messages, ["Time has wrong format. Use one of these formats instead: "
"HH:MM; HH:MM:SS; HH:MM:SS.uuuuuu"])
else: else:
self.fail("ValidationError was not properly raised") self.fail("ValidationError was not properly raised")
def test_from_native_invalid_format(self):
"""
Make sure from_native() raises a ValidationError on passing an invalid format.
"""
f = serializers.TimeField()
try:
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"])
else:
self.fail("ValidationError was not properly raised")
def test_to_native(self):
"""
Make sure to_native() returns isoformat as default.
"""
f = serializers.TimeField()
result_1 = f.to_native(datetime.time(4, 31))
result_2 = f.to_native(datetime.time(4, 31, 59))
result_3 = f.to_native(datetime.time(4, 31, 59, 200))
self.assertEqual('04:31:00', result_1)
self.assertEqual('04:31:59', result_2)
self.assertEqual('04:31:59.000200', result_3)
def test_to_native_custom_format(self):
"""
Make sure to_native() returns correct custom format.
"""
f = serializers.TimeField(output_format="%H - %S [%f]")
result_1 = f.to_native(datetime.time(4, 31))
result_2 = f.to_native(datetime.time(4, 31, 59))
result_3 = f.to_native(datetime.time(4, 31, 59, 200))
self.assertEqual('04 - 00 [000000]', result_1)
self.assertEqual('04 - 59 [000000]', result_2)
self.assertEqual('04 - 59 [000200]', result_3)

View File

@ -65,7 +65,7 @@ class IntegrationTestFiltering(TestCase):
self.objects = FilterableItem.objects self.objects = FilterableItem.objects
self.data = [ self.data = [
{'id': obj.id, 'text': obj.text, 'decimal': obj.decimal, 'date': obj.date} {'id': obj.id, 'text': obj.text, 'decimal': obj.decimal, 'date': obj.date.isoformat()}
for obj in self.objects.all() for obj in self.objects.all()
] ]
@ -95,7 +95,7 @@ class IntegrationTestFiltering(TestCase):
request = factory.get('/?date=%s' % search_date) # search_date str: '2012-09-22' request = factory.get('/?date=%s' % search_date) # search_date str: '2012-09-22'
response = view(request).render() response = view(request).render()
self.assertEquals(response.status_code, status.HTTP_200_OK) self.assertEquals(response.status_code, status.HTTP_200_OK)
expected_data = [f for f in self.data if f['date'] == search_date] expected_data = [f for f in self.data if datetime.datetime.strptime(f['date'], '%Y-%m-%d').date() == search_date]
self.assertEquals(response.data, expected_data) self.assertEquals(response.data, expected_data)
@unittest.skipUnless(django_filters, 'django-filters not installed') @unittest.skipUnless(django_filters, 'django-filters not installed')
@ -125,7 +125,7 @@ class IntegrationTestFiltering(TestCase):
request = factory.get('/?date=%s' % search_date) # search_date str: '2012-10-02' request = factory.get('/?date=%s' % search_date) # search_date str: '2012-10-02'
response = view(request).render() response = view(request).render()
self.assertEquals(response.status_code, status.HTTP_200_OK) self.assertEquals(response.status_code, status.HTTP_200_OK)
expected_data = [f for f in self.data if f['date'] > search_date] expected_data = [f for f in self.data if datetime.datetime.strptime(f['date'], '%Y-%m-%d').date() > search_date]
self.assertEquals(response.data, expected_data) self.assertEquals(response.data, expected_data)
# Tests that the text filter set with 'icontains' in the filter class works. # Tests that the text filter set with 'icontains' in the filter class works.
@ -142,7 +142,8 @@ class IntegrationTestFiltering(TestCase):
request = factory.get('/?decimal=%s&date=%s' % (search_decimal, search_date)) request = factory.get('/?decimal=%s&date=%s' % (search_decimal, search_date))
response = view(request).render() response = view(request).render()
self.assertEquals(response.status_code, status.HTTP_200_OK) self.assertEquals(response.status_code, status.HTTP_200_OK)
expected_data = [f for f in self.data if f['date'] > search_date and expected_data = [f for f in self.data if
datetime.datetime.strptime(f['date'], '%Y-%m-%d').date() > search_date and
f['decimal'] < search_decimal] f['decimal'] < search_decimal]
self.assertEquals(response.data, expected_data) self.assertEquals(response.data, expected_data)

View File

@ -112,7 +112,7 @@ class IntegrationTestPaginationAndFiltering(TestCase):
self.objects = FilterableItem.objects self.objects = FilterableItem.objects
self.data = [ self.data = [
{'id': obj.id, 'text': obj.text, 'decimal': obj.decimal, 'date': obj.date} {'id': obj.id, 'text': obj.text, 'decimal': obj.decimal, 'date': obj.date.isoformat()}
for obj in self.objects.all() for obj in self.objects.all()
] ]
self.view = FilterFieldsRootView.as_view() self.view = FilterFieldsRootView.as_view()

View File

@ -107,7 +107,7 @@ class BasicTests(TestCase):
self.expected = { self.expected = {
'email': 'tom@example.com', 'email': 'tom@example.com',
'content': 'Happy new year!', 'content': 'Happy new year!',
'created': datetime.datetime(2012, 1, 1), 'created': '2012-01-01T00:00:00',
'sub_comment': 'And Merry Christmas!' 'sub_comment': 'And Merry Christmas!'
} }
self.person_data = {'name': 'dwight', 'age': 35} self.person_data = {'name': 'dwight', 'age': 35}