This commit is contained in:
Tim Saylor 2015-07-13 14:07:10 +00:00
commit 756003a887
2 changed files with 46 additions and 1 deletions

View File

@ -903,6 +903,11 @@ class DateTimeField(Field):
When `self.default_timezone` is not `None`, always return aware 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): if (self.default_timezone is not None) and not timezone.is_aware(value):
# If a timezone is active we want to use it, but if not we want to use the timezone
# specified for this field over the system's default timezone.
if hasattr(timezone._active, 'value'):
return timezone.make_aware(value, timezone._active.value)
else:
return timezone.make_aware(value, self.default_timezone) return timezone.make_aware(value, self.default_timezone)
elif (self.default_timezone is None) and timezone.is_aware(value): elif (self.default_timezone is None) and timezone.is_aware(value):
return timezone.make_naive(value, timezone.UTC()) return timezone.make_naive(value, timezone.UTC())
@ -936,6 +941,11 @@ class DateTimeField(Field):
self.fail('invalid', format=humanized_format) self.fail('invalid', format=humanized_format)
def to_representation(self, value): def to_representation(self, value):
if timezone.is_aware(value):
# convert the datetime to the timezone the user is expecting
tz = getattr(timezone._active, "value", self.default_timezone)
value = timezone.localtime(value, tz)
if self.format is None: if self.format is None:
return value return value

View File

@ -4,6 +4,7 @@ from decimal import Decimal
import django import django
import pytest import pytest
from django.test.utils import override_settings
from django.utils import timezone from django.utils import timezone
import rest_framework import rest_framework
@ -848,6 +849,40 @@ class TestNoOutputFormatDateField(FieldValues):
field = serializers.DateField(format=None) field = serializers.DateField(format=None)
class FakeTimezone(datetime.tzinfo):
def __repr__(self):
return "<FakeTimezone>"
def utcoffset(self, dt):
return datetime.timedelta(1)
def tzname(self, dt):
return "FakeTimezone"
def dst(self, dt):
return datetime.timedelta(1)
class TestAwareDateTimeField:
@override_settings(USE_TZ=True)
def test_with_timezone_active(self):
naive_now = timezone.make_naive(timezone.now(), timezone.UTC())
timezone.activate(FakeTimezone())
field = serializers.DateTimeField(default_timezone=timezone.UTC())
aware_now = field.enforce_timezone(naive_now)
assert aware_now.tzname() == 'FakeTimezone'
timezone.deactivate()
@override_settings(USE_TZ=True)
def test_without_timezone_active(self):
naive_now = timezone.make_naive(timezone.now(), timezone.UTC())
field = serializers.DateTimeField(default_timezone=timezone.UTC())
aware_now = field.enforce_timezone(naive_now)
assert aware_now.tzname() == 'UTC'
class TestDateTimeField(FieldValues): class TestDateTimeField(FieldValues):
""" """
Valid and invalid values for `DateTimeField`. Valid and invalid values for `DateTimeField`.