diff options
| author | Tom Christie | 2013-03-05 17:50:28 +0000 |
|---|---|---|
| committer | Tom Christie | 2013-03-05 17:50:28 +0000 |
| commit | c20ebe95f6707d63373d9c583e90bcbc6e021899 (patch) | |
| tree | 8c51d642ef180b37f6799a45ccced9b71665fb7c /rest_framework/fields.py | |
| parent | 6e7ddd579b6604d1b0d6da8e4d09762be4520e35 (diff) | |
| parent | 5e5cd6f7f7357d68d5c10500ec0379e49d679202 (diff) | |
| download | django-rest-framework-c20ebe95f6707d63373d9c583e90bcbc6e021899.tar.bz2 | |
Merge datetime formats
Diffstat (limited to 'rest_framework/fields.py')
| -rw-r--r-- | rest_framework/fields.py | 151 |
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): |
