Author: aaugustin
Date: 2011-11-19 15:27:20 -0800 (Sat, 19 Nov 2011)
New Revision: 17117

Added:
   django/trunk/tests/modeltests/timezones/fixtures/tz_users.xml
Removed:
   django/trunk/tests/modeltests/timezones/fixtures/users.xml
Modified:
   django/trunk/django/db/models/fields/__init__.py
   django/trunk/docs/topics/i18n/timezones.txt
   django/trunk/tests/modeltests/timezones/tests.py
Log:
Fixed #17263 -- Added a warning when a naive datetime reaches the database 
layer while time zone support is enabled.

After this commit, timezones.AdminTests will raise warnings because the 
sessions contrib app hasn't been upgraded to support time zones yet.
This will be fixed in an upcoming commit.



Modified: django/trunk/django/db/models/fields/__init__.py
===================================================================
--- django/trunk/django/db/models/fields/__init__.py    2011-11-19 22:57:47 UTC 
(rev 17116)
+++ django/trunk/django/db/models/fields/__init__.py    2011-11-19 23:27:20 UTC 
(rev 17117)
@@ -2,6 +2,7 @@
 import datetime
 import decimal
 import math
+import warnings
 from itertools import tee
 
 from django.db import connection
@@ -789,6 +790,9 @@
             # 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(u"DateTimeField received a naive datetime (%s)"
+                          u" while time zone support is active." % value,
+                          RuntimeWarning)
             default_timezone = timezone.get_default_timezone()
             value = timezone.make_aware(value, default_timezone)
         return value

Modified: django/trunk/docs/topics/i18n/timezones.txt
===================================================================
--- django/trunk/docs/topics/i18n/timezones.txt 2011-11-19 22:57:47 UTC (rev 
17116)
+++ django/trunk/docs/topics/i18n/timezones.txt 2011-11-19 23:27:20 UTC (rev 
17117)
@@ -106,9 +106,9 @@
 ----------------------------------------
 
 When :setting:`USE_TZ` is ``True``, Django still accepts naive datetime
-objects, in order to preserve backwards-compatibility. It attempts to make them
-aware by interpreting them in the :ref:`default time zone
-<default-current-time-zone>`.
+objects, in order to preserve backwards-compatibility. When the database layer
+receives one, it attempts to make it aware by interpreting it in the
+:ref:`default time zone <default-current-time-zone>` and raises a warning.
 
 Unfortunately, during DST transitions, some datetimes don't exist or are
 ambiguous. In such situations, pytz_ raises an exception. Other
@@ -421,11 +421,22 @@
 So the second step is to refactor your code wherever you instanciate datetime
 objects to make them aware. This can be done incrementally.
 :mod:`django.utils.timezone` defines some handy helpers for compatibility
-code: :func:`~django.utils.timezone.is_aware`,
+code: :func:`~django.utils.timezone.now`,
+:func:`~django.utils.timezone.is_aware`,
 :func:`~django.utils.timezone.is_naive`,
 :func:`~django.utils.timezone.make_aware`, and
 :func:`~django.utils.timezone.make_naive`.
 
+Finally, in order to help you locate code that needs upgrading, Django raises
+a warning when you attempt to save a naive datetime to the database. During
+development, you can turn such warnings into exceptions and get a traceback
+by adding to your settings file::
+
+    import warnings
+    warnings.filterwarnings(
+            'error', r"DateTimeField received a naive datetime",
+            RuntimeWarning, r'django\.db\.models\.fields')
+
 .. _pytz: http://pytz.sourceforge.net/
 .. _these issues: http://pytz.sourceforge.net/#problems-with-localtime
 .. _tz database: http://en.wikipedia.org/wiki/Tz_database

Copied: django/trunk/tests/modeltests/timezones/fixtures/tz_users.xml (from rev 
17113, django/trunk/tests/modeltests/timezones/fixtures/users.xml)
===================================================================
--- django/trunk/tests/modeltests/timezones/fixtures/tz_users.xml               
                (rev 0)
+++ django/trunk/tests/modeltests/timezones/fixtures/tz_users.xml       
2011-11-19 23:27:20 UTC (rev 17117)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<django-objects version="1.0">
+    <object pk="100" model="auth.user">
+        <field type="CharField" name="username">super</field>
+        <field type="CharField" name="first_name">Super</field>
+        <field type="CharField" name="last_name">User</field>
+        <field type="CharField" name="email">su...@example.com</field>
+        <field type="CharField" 
name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field>
+        <field type="BooleanField" name="is_staff">True</field>
+        <field type="BooleanField" name="is_active">True</field>
+        <field type="BooleanField" name="is_superuser">True</field>
+        <field type="DateTimeField" name="last_login">2001-01-01 
00:00:00+00:00</field>
+        <field type="DateTimeField" name="date_joined">2001-01-01 
00:00:00+00:00</field>
+        <field to="auth.group" name="groups" rel="ManyToManyRel"></field>
+        <field to="auth.permission" name="user_permissions" 
rel="ManyToManyRel"></field>
+    </object>
+</django-objects>

Deleted: django/trunk/tests/modeltests/timezones/fixtures/users.xml
===================================================================
--- django/trunk/tests/modeltests/timezones/fixtures/users.xml  2011-11-19 
22:57:47 UTC (rev 17116)
+++ django/trunk/tests/modeltests/timezones/fixtures/users.xml  2011-11-19 
23:27:20 UTC (rev 17117)
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<django-objects version="1.0">
-    <object pk="100" model="auth.user">
-        <field type="CharField" name="username">super</field>
-        <field type="CharField" name="first_name">Super</field>
-        <field type="CharField" name="last_name">User</field>
-        <field type="CharField" name="email">su...@example.com</field>
-        <field type="CharField" 
name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field>
-        <field type="BooleanField" name="is_staff">True</field>
-        <field type="BooleanField" name="is_active">True</field>
-        <field type="BooleanField" name="is_superuser">True</field>
-        <field type="DateTimeField" name="last_login">2007-05-30 
13:20:10</field>
-        <field type="DateTimeField" name="date_joined">2007-05-30 
13:20:10</field>
-        <field to="auth.group" name="groups" rel="ManyToManyRel"></field>
-        <field to="auth.permission" name="user_permissions" 
rel="ManyToManyRel"></field>
-    </object>
-</django-objects>
\ No newline at end of file

Modified: django/trunk/tests/modeltests/timezones/tests.py
===================================================================
--- django/trunk/tests/modeltests/timezones/tests.py    2011-11-19 22:57:47 UTC 
(rev 17116)
+++ django/trunk/tests/modeltests/timezones/tests.py    2011-11-19 23:27:20 UTC 
(rev 17117)
@@ -3,6 +3,7 @@
 import datetime
 import os
 import time
+import warnings
 
 try:
     import pytz
@@ -238,7 +239,11 @@
 
     def test_naive_datetime(self):
         dt = datetime.datetime(2011, 9, 1, 13, 20, 30)
-        Event.objects.create(dt=dt)
+        with warnings.catch_warnings(record=True) as recorded:
+            Event.objects.create(dt=dt)
+            self.assertEqual(len(recorded), 1)
+            msg = str(recorded[0].message)
+            self.assertTrue(msg.startswith("DateTimeField received a naive 
datetime"))
         event = Event.objects.get()
         # naive datetimes are interpreted in local time
         self.assertEqual(event.dt, dt.replace(tzinfo=EAT))
@@ -246,7 +251,11 @@
     @skipUnlessDBFeature('supports_microsecond_precision')
     def test_naive_datetime_with_microsecond(self):
         dt = datetime.datetime(2011, 9, 1, 13, 20, 30, 405060)
-        Event.objects.create(dt=dt)
+        with warnings.catch_warnings(record=True) as recorded:
+            Event.objects.create(dt=dt)
+            self.assertEqual(len(recorded), 1)
+            msg = str(recorded[0].message)
+            self.assertTrue(msg.startswith("DateTimeField received a naive 
datetime"))
         event = Event.objects.get()
         # naive datetimes are interpreted in local time
         self.assertEqual(event.dt, dt.replace(tzinfo=EAT))
@@ -254,7 +263,11 @@
     @skipIfDBFeature('supports_microsecond_precision')
     def test_naive_datetime_with_microsecond_unsupported(self):
         dt = datetime.datetime(2011, 9, 1, 13, 20, 30, 405060)
-        Event.objects.create(dt=dt)
+        with warnings.catch_warnings(record=True) as recorded:
+            Event.objects.create(dt=dt)
+            self.assertEqual(len(recorded), 1)
+            msg = str(recorded[0].message)
+            self.assertTrue(msg.startswith("DateTimeField received a naive 
datetime"))
         event = Event.objects.get()
         # microseconds are lost during a round-trip in the database
         # naive datetimes are interpreted in local time
@@ -294,7 +307,7 @@
         self.assertEqual(event.dt, dt)
 
     def test_auto_now_and_auto_now_add(self):
-        now = datetime.datetime.utcnow().replace(tzinfo=UTC)
+        now = timezone.now()
         past = now - datetime.timedelta(seconds=2)
         future = now + datetime.timedelta(seconds=2)
         Timestamp.objects.create()
@@ -824,7 +837,7 @@
 class AdminTests(BaseDateTimeTests):
 
     urls = 'modeltests.timezones.urls'
-    fixtures = ['users.xml']
+    fixtures = ['tz_users.xml']
 
     def setUp(self):
         self.client.login(username='super', password='secret')

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-updates@googlegroups.com.
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to