mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-26 11:33:59 +03:00
Coerce dates etc to ISO_8601 in seralizer, by default.
This commit is contained in:
parent
22af49bf8f
commit
79715f01f8
|
@ -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.')
|
'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.max_digits = max_digits
|
||||||
self.decimal_places = decimal_places
|
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)
|
super(DecimalField, self).__init__(**kwargs)
|
||||||
if max_value is not None:
|
if max_value is not None:
|
||||||
self.validators.append(validators.MaxValueValidator(max_value))
|
self.validators.append(validators.MaxValueValidator(max_value))
|
||||||
|
@ -510,12 +512,12 @@ class DateField(Field):
|
||||||
default_error_messages = {
|
default_error_messages = {
|
||||||
'invalid': _('Date has wrong format. Use one of these formats instead: {format}'),
|
'invalid': _('Date has wrong format. Use one of these formats instead: {format}'),
|
||||||
}
|
}
|
||||||
input_formats = api_settings.DATE_INPUT_FORMATS
|
|
||||||
format = api_settings.DATE_FORMAT
|
format = api_settings.DATE_FORMAT
|
||||||
|
input_formats = api_settings.DATE_INPUT_FORMATS
|
||||||
|
|
||||||
def __init__(self, input_formats=None, format=None, *args, **kwargs):
|
def __init__(self, format=None, input_formats=None, *args, **kwargs):
|
||||||
self.input_formats = input_formats if input_formats is not None else self.input_formats
|
|
||||||
self.format = format if format is not None else self.format
|
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)
|
super(DateField, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def to_internal_value(self, value):
|
def to_internal_value(self, value):
|
||||||
|
@ -569,12 +571,12 @@ class DateTimeField(Field):
|
||||||
default_error_messages = {
|
default_error_messages = {
|
||||||
'invalid': _('Datetime has wrong format. Use one of these formats instead: {format}'),
|
'invalid': _('Datetime has wrong format. Use one of these formats instead: {format}'),
|
||||||
}
|
}
|
||||||
input_formats = api_settings.DATETIME_INPUT_FORMATS
|
|
||||||
format = api_settings.DATETIME_FORMAT
|
format = api_settings.DATETIME_FORMAT
|
||||||
|
input_formats = api_settings.DATETIME_INPUT_FORMATS
|
||||||
|
|
||||||
def __init__(self, input_formats=None, format=None, *args, **kwargs):
|
def __init__(self, format=None, input_formats=None, *args, **kwargs):
|
||||||
self.input_formats = input_formats if input_formats is not None else self.input_formats
|
|
||||||
self.format = format if format is not None else self.format
|
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)
|
super(DateTimeField, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def to_internal_value(self, value):
|
def to_internal_value(self, value):
|
||||||
|
@ -634,12 +636,12 @@ class TimeField(Field):
|
||||||
default_error_messages = {
|
default_error_messages = {
|
||||||
'invalid': _('Time has wrong format. Use one of these formats instead: {format}'),
|
'invalid': _('Time has wrong format. Use one of these formats instead: {format}'),
|
||||||
}
|
}
|
||||||
input_formats = api_settings.TIME_INPUT_FORMATS
|
|
||||||
format = api_settings.TIME_FORMAT
|
format = api_settings.TIME_FORMAT
|
||||||
|
input_formats = api_settings.TIME_INPUT_FORMATS
|
||||||
|
|
||||||
def __init__(self, input_formats=None, format=None, *args, **kwargs):
|
def __init__(self, format=None, input_formats=None, *args, **kwargs):
|
||||||
self.input_formats = input_formats if input_formats is not None else self.input_formats
|
|
||||||
self.format = format if format is not None else self.format
|
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)
|
super(TimeField, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def from_native(self, value):
|
def from_native(self, value):
|
||||||
|
|
|
@ -97,24 +97,19 @@ DEFAULTS = {
|
||||||
'URL_FIELD_NAME': 'url',
|
'URL_FIELD_NAME': 'url',
|
||||||
|
|
||||||
# Input and output formats
|
# Input and output formats
|
||||||
'DATE_INPUT_FORMATS': (
|
'DATE_FORMAT': ISO_8601,
|
||||||
ISO_8601,
|
'DATE_INPUT_FORMATS': (ISO_8601,),
|
||||||
),
|
|
||||||
'DATE_FORMAT': None,
|
|
||||||
|
|
||||||
'DATETIME_INPUT_FORMATS': (
|
'DATETIME_FORMAT': ISO_8601,
|
||||||
ISO_8601,
|
'DATETIME_INPUT_FORMATS': (ISO_8601,),
|
||||||
),
|
|
||||||
'DATETIME_FORMAT': None,
|
|
||||||
|
|
||||||
'TIME_INPUT_FORMATS': (
|
'TIME_FORMAT': ISO_8601,
|
||||||
ISO_8601,
|
'TIME_INPUT_FORMATS': (ISO_8601,),
|
||||||
),
|
|
||||||
'TIME_FORMAT': None,
|
|
||||||
|
|
||||||
# Encoding
|
# Encoding
|
||||||
'UNICODE_JSON': True,
|
'UNICODE_JSON': True,
|
||||||
'COMPACT_JSON': True
|
'COMPACT_JSON': True,
|
||||||
|
'COERCE_DECIMAL_TO_STRING': True
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,11 @@ from __future__ import unicode_literals
|
||||||
import datetime
|
import datetime
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.conf.urls import patterns, url
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.utils import unittest
|
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 import generics, serializers, status, filters
|
||||||
from rest_framework.compat import django_filters
|
from rest_framework.compat import django_filters
|
||||||
from rest_framework.test import APIRequestFactory
|
from rest_framework.test import APIRequestFactory
|
||||||
|
@ -102,7 +103,7 @@ if django_filters:
|
||||||
|
|
||||||
class CommonFilteringTestCase(TestCase):
|
class CommonFilteringTestCase(TestCase):
|
||||||
def _serialize_object(self, obj):
|
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):
|
def setUp(self):
|
||||||
"""
|
"""
|
||||||
|
@ -153,7 +154,7 @@ class IntegrationTestFiltering(CommonFilteringTestCase):
|
||||||
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.assertEqual(response.status_code, status.HTTP_200_OK)
|
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)
|
self.assertEqual(response.data, expected_data)
|
||||||
|
|
||||||
@unittest.skipUnless(django_filters, 'django-filter not installed')
|
@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'
|
request = factory.get('/', {'date': '%s' % search_date}) # search_date str: '2012-10-02'
|
||||||
response = view(request).render()
|
response = view(request).render()
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
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)
|
self.assertEqual(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.
|
||||||
|
@ -229,7 +230,7 @@ class IntegrationTestFiltering(CommonFilteringTestCase):
|
||||||
})
|
})
|
||||||
response = view(request).render()
|
response = view(request).render()
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
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]
|
Decimal(f['decimal']) < search_decimal]
|
||||||
self.assertEqual(response.data, expected_data)
|
self.assertEqual(response.data, expected_data)
|
||||||
|
|
||||||
|
@ -481,9 +482,9 @@ class DjangoFilterOrderingTests(TestCase):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
response.data,
|
response.data,
|
||||||
[
|
[
|
||||||
{'id': 3, 'date': datetime.date(2014, 10, 8), 'text': 'cde'},
|
{'id': 3, 'date': '2014-10-08', 'text': 'cde'},
|
||||||
{'id': 2, 'date': datetime.date(2013, 10, 8), 'text': 'bcd'},
|
{'id': 2, 'date': '2013-10-08', 'text': 'bcd'},
|
||||||
{'id': 1, 'date': datetime.date(2012, 10, 8), 'text': 'abc'}
|
{'id': 1, 'date': '2012-10-08', 'text': 'abc'}
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ class IntegrationTestPaginationAndFiltering(TestCase):
|
||||||
|
|
||||||
self.objects = FilterableItem.objects
|
self.objects = FilterableItem.objects
|
||||||
self.data = [
|
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()
|
for obj in self.objects.all()
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user