diff options
| author | Tom Christie | 2014-09-22 12:25:57 +0100 | 
|---|---|---|
| committer | Tom Christie | 2014-09-22 12:25:57 +0100 | 
| commit | af46fd6b00f1d7f018049c19094af58acb1415fb (patch) | |
| tree | be18854dcc4138713a3244fedc093316fe165769 /rest_framework | |
| parent | cf72b9a8b755652cec4ad19a27488e3a79c2e401 (diff) | |
| download | django-rest-framework-af46fd6b00f1d7f018049c19094af58acb1415fb.tar.bz2 | |
Field tests and associated cleanup
Diffstat (limited to 'rest_framework')
| -rw-r--r-- | rest_framework/fields.py | 64 | 
1 files changed, 31 insertions, 33 deletions
| diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 0c78b3fb..db75ddf9 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -12,7 +12,6 @@ from rest_framework.utils import html, representation, humanize_datetime  import datetime  import decimal  import inspect -import warnings  class empty: @@ -395,7 +394,7 @@ class IntegerField(Field):  class FloatField(Field):      default_error_messages = { -        'invalid': _("'%s' value must be a float."), +        'invalid': _("A valid number is required."),      }      def __init__(self, **kwargs): @@ -410,20 +409,20 @@ class FloatField(Field):      def to_internal_value(self, value):          if value is None:              return None -        return float(value) +        try: +            return float(value) +        except (TypeError, ValueError): +            self.fail('invalid')      def to_representation(self, value):          if value is None:              return None -        try: -            return float(value) -        except (TypeError, ValueError): -            self.fail('invalid', value=value) +        return float(value)  class DecimalField(Field):      default_error_messages = { -        'invalid': _('Enter a number.'), +        'invalid': _('A valid number is required.'),          'max_value': _('Ensure this value is less than or equal to {max_value}.'),          'min_value': _('Ensure this value is greater than or equal to {min_value}.'),          'max_digits': _('Ensure that there are no more than {max_digits} digits in total.'), @@ -485,7 +484,7 @@ class DecimalField(Field):          if self.decimal_places is not None and decimals > self.decimal_places:              self.fail('max_decimal_places', max_decimal_places=self.decimal_places)          if self.max_digits is not None and self.decimal_places is not None and whole_digits > (self.max_digits - self.decimal_places): -            self.fail('max_whole_digits', max_while_digits=self.max_digits - self.decimal_places) +            self.fail('max_whole_digits', max_whole_digits=self.max_digits - self.decimal_places)          return value @@ -511,6 +510,7 @@ class DecimalField(Field):  class DateField(Field):      default_error_messages = {          'invalid': _('Date has wrong format. Use one of these formats instead: {format}'), +        'datetime': _('Expected a date but got a datetime.'),      }      format = api_settings.DATE_FORMAT      input_formats = api_settings.DATE_INPUT_FORMATS @@ -525,12 +525,7 @@ class DateField(Field):              return None          if isinstance(value, datetime.datetime): -            if timezone and settings.USE_TZ and timezone.is_aware(value): -                # Convert aware datetimes to the default time zone -                # before casting them to dates (#17742). -                default_timezone = timezone.get_default_timezone() -                value = timezone.make_naive(value, default_timezone) -            return value.date() +            self.fail('datetime')          if isinstance(value, datetime.date):              return value @@ -570,35 +565,38 @@ class DateField(Field):  class DateTimeField(Field):      default_error_messages = {          'invalid': _('Datetime has wrong format. Use one of these formats instead: {format}'), +        'date': _('Expected a datetime but got a date.'),      }      format = api_settings.DATETIME_FORMAT      input_formats = api_settings.DATETIME_INPUT_FORMATS +    default_timezone = timezone.get_default_timezone() if settings.USE_TZ else None -    def __init__(self, format=None, input_formats=None, *args, **kwargs): +    def __init__(self, format=None, input_formats=None, default_timezone=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 +        self.default_timezone = default_timezone if default_timezone is not None else self.default_timezone          super(DateTimeField, self).__init__(*args, **kwargs) +    def enforce_timezone(self, value): +        """ +        When `self.default_timezone` is `None`, always return naive datetimes. +        When `self.default_timezone` is not `None`, always return aware datetimes. +        """ +        if (self.default_timezone is not None) and not timezone.is_aware(value): +            return timezone.make_aware(value, self.default_timezone) +        elif (self.default_timezone is None) and timezone.is_aware(value): +            return timezone.make_naive(value, timezone.UTC()) +        return value +      def to_internal_value(self, value):          if value in (None, ''):              return None -        if isinstance(value, datetime.datetime): -            return value +        if isinstance(value, datetime.date) and not isinstance(value, datetime.datetime): +            self.fail('date') -        if isinstance(value, datetime.date): -            value = datetime.datetime(value.year, value.month, value.day) -            if settings.USE_TZ: -                # For backwards compatibility, interpret naive datetimes in -                # local time. This won't work during DST change, but we can't -                # do much about it, so we let the exceptions percolate up the -                # call stack. -                warnings.warn("DateTimeField received a naive datetime (%s)" -                              " while time zone support is active." % value, -                              RuntimeWarning) -                default_timezone = timezone.get_default_timezone() -                value = timezone.make_aware(value, default_timezone) -            return value +        if isinstance(value, datetime.datetime): +            return self.enforce_timezone(value)          for format in self.input_formats:              if format.lower() == ISO_8601: @@ -608,14 +606,14 @@ class DateTimeField(Field):                      pass                  else:                      if parsed is not None: -                        return parsed +                        return self.enforce_timezone(parsed)              else:                  try:                      parsed = datetime.datetime.strptime(value, format)                  except (ValueError, TypeError):                      pass                  else: -                    return parsed +                    return self.enforce_timezone(parsed)          humanized_format = humanize_datetime.datetime_formats(self.input_formats)          self.fail('invalid', format=humanized_format) | 
