Coerce dates etc to ISO_8601 in seralizer, by default.

This commit is contained in:
Tom Christie 2014-09-12 12:10:22 +01:00
parent 22af49bf8f
commit 79715f01f8
4 changed files with 31 additions and 33 deletions

View File

@ -431,10 +431,12 @@ class DecimalField(Field):
'max_whole_digits': _('Ensure that there are no more than {max_whole_digits} digits before the decimal point.')
}
def __init__(self, max_digits, decimal_places, coerce_to_string=True, max_value=None, min_value=None, **kwargs):
coerce_to_string = api_settings.COERCE_DECIMAL_TO_STRING
def __init__(self, max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None, **kwargs):
self.max_digits = max_digits
self.decimal_places = decimal_places
self.coerce_to_string = coerce_to_string
self.coerce_to_string = coerce_to_string if (coerce_to_string is not None) else self.coerce_to_string
super(DecimalField, self).__init__(**kwargs)
if max_value is not None:
self.validators.append(validators.MaxValueValidator(max_value))
@ -510,12 +512,12 @@ class DateField(Field):
default_error_messages = {
'invalid': _('Date has wrong format. Use one of these formats instead: {format}'),
}
input_formats = api_settings.DATE_INPUT_FORMATS
format = api_settings.DATE_FORMAT
input_formats = api_settings.DATE_INPUT_FORMATS
def __init__(self, input_formats=None, format=None, *args, **kwargs):
self.input_formats = input_formats if input_formats is not None else self.input_formats
def __init__(self, format=None, input_formats=None, *args, **kwargs):
self.format = format if format is not None else self.format
self.input_formats = input_formats if input_formats is not None else self.input_formats
super(DateField, self).__init__(*args, **kwargs)
def to_internal_value(self, value):
@ -569,12 +571,12 @@ class DateTimeField(Field):
default_error_messages = {
'invalid': _('Datetime has wrong format. Use one of these formats instead: {format}'),
}
input_formats = api_settings.DATETIME_INPUT_FORMATS
format = api_settings.DATETIME_FORMAT
input_formats = api_settings.DATETIME_INPUT_FORMATS
def __init__(self, input_formats=None, format=None, *args, **kwargs):
self.input_formats = input_formats if input_formats is not None else self.input_formats
def __init__(self, format=None, input_formats=None, *args, **kwargs):
self.format = format if format is not None else self.format
self.input_formats = input_formats if input_formats is not None else self.input_formats
super(DateTimeField, self).__init__(*args, **kwargs)
def to_internal_value(self, value):
@ -634,12 +636,12 @@ class TimeField(Field):
default_error_messages = {
'invalid': _('Time has wrong format. Use one of these formats instead: {format}'),
}
input_formats = api_settings.TIME_INPUT_FORMATS
format = api_settings.TIME_FORMAT
input_formats = api_settings.TIME_INPUT_FORMATS
def __init__(self, input_formats=None, format=None, *args, **kwargs):
self.input_formats = input_formats if input_formats is not None else self.input_formats
def __init__(self, format=None, input_formats=None, *args, **kwargs):
self.format = format if format is not None else self.format
self.input_formats = input_formats if input_formats is not None else self.input_formats
super(TimeField, self).__init__(*args, **kwargs)
def from_native(self, value):

View File

@ -97,24 +97,19 @@ DEFAULTS = {
'URL_FIELD_NAME': 'url',
# Input and output formats
'DATE_INPUT_FORMATS': (
ISO_8601,
),
'DATE_FORMAT': None,
'DATE_FORMAT': ISO_8601,
'DATE_INPUT_FORMATS': (ISO_8601,),
'DATETIME_INPUT_FORMATS': (
ISO_8601,
),
'DATETIME_FORMAT': None,
'DATETIME_FORMAT': ISO_8601,
'DATETIME_INPUT_FORMATS': (ISO_8601,),
'TIME_INPUT_FORMATS': (
ISO_8601,
),
'TIME_FORMAT': None,
'TIME_FORMAT': ISO_8601,
'TIME_INPUT_FORMATS': (ISO_8601,),
# Encoding
'UNICODE_JSON': True,
'COMPACT_JSON': True
'COMPACT_JSON': True,
'COERCE_DECIMAL_TO_STRING': True
}

View File

@ -2,10 +2,11 @@ from __future__ import unicode_literals
import datetime
from decimal import Decimal
from django.db import models
from django.conf.urls import patterns, url
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.utils import unittest
from django.conf.urls import patterns, url
from django.utils.dateparse import parse_date
from rest_framework import generics, serializers, status, filters
from rest_framework.compat import django_filters
from rest_framework.test import APIRequestFactory
@ -102,7 +103,7 @@ if django_filters:
class CommonFilteringTestCase(TestCase):
def _serialize_object(self, obj):
return {'id': obj.id, 'text': obj.text, 'decimal': str(obj.decimal), 'date': obj.date}
return {'id': obj.id, 'text': obj.text, 'decimal': str(obj.decimal), 'date': obj.date.isoformat()}
def setUp(self):
"""
@ -153,7 +154,7 @@ class IntegrationTestFiltering(CommonFilteringTestCase):
request = factory.get('/', {'date': '%s' % search_date}) # search_date str: '2012-09-22'
response = view(request).render()
self.assertEqual(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 parse_date(f['date']) == search_date]
self.assertEqual(response.data, expected_data)
@unittest.skipUnless(django_filters, 'django-filter not installed')
@ -209,7 +210,7 @@ class IntegrationTestFiltering(CommonFilteringTestCase):
request = factory.get('/', {'date': '%s' % search_date}) # search_date str: '2012-10-02'
response = view(request).render()
self.assertEqual(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 parse_date(f['date']) > search_date]
self.assertEqual(response.data, expected_data)
# Tests that the text filter set with 'icontains' in the filter class works.
@ -229,7 +230,7 @@ class IntegrationTestFiltering(CommonFilteringTestCase):
})
response = view(request).render()
self.assertEqual(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 parse_date(f['date']) > search_date and
Decimal(f['decimal']) < search_decimal]
self.assertEqual(response.data, expected_data)
@ -481,9 +482,9 @@ class DjangoFilterOrderingTests(TestCase):
self.assertEqual(
response.data,
[
{'id': 3, 'date': datetime.date(2014, 10, 8), 'text': 'cde'},
{'id': 2, 'date': datetime.date(2013, 10, 8), 'text': 'bcd'},
{'id': 1, 'date': datetime.date(2012, 10, 8), 'text': 'abc'}
{'id': 3, 'date': '2014-10-08', 'text': 'cde'},
{'id': 2, 'date': '2013-10-08', 'text': 'bcd'},
{'id': 1, 'date': '2012-10-08', 'text': 'abc'}
]
)

View File

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