summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2016-03-10 09:22:09 -0500
committerTim Graham <timograham@gmail.com>2016-03-10 19:16:20 -0500
commit5b6c751230c7ec33eebc564c15ab299ef8f6852a (patch)
treef8e765e80e611a52d6da96438cb7473c412e8f1a
parent301edde86d07fe27a4aa002b1546d2a3002190dc (diff)
[1.9.x] Fixed #26324 -- Fixed DurationField with fractional seconds on SQLite.
Backport of 4f0cd0fd162122da96978b357ac9fc9534529410 from master
-rw-r--r--django/db/models/fields/__init__.py3
-rw-r--r--docs/releases/1.8.12.txt3
-rw-r--r--docs/releases/1.9.5.txt3
-rw-r--r--tests/model_fields/test_durationfield.py6
4 files changed, 14 insertions, 1 deletions
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index df2e3b45de..cf7a3c32ac 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -1665,7 +1665,8 @@ class DurationField(Field):
return value
if value is None:
return None
- return value.total_seconds() * 1000000
+ # Discard any fractional microseconds due to floating point arithmetic.
+ return int(round(value.total_seconds() * 1000000))
def get_db_converters(self, connection):
converters = []
diff --git a/docs/releases/1.8.12.txt b/docs/releases/1.8.12.txt
index 26735b8278..0052a90b0d 100644
--- a/docs/releases/1.8.12.txt
+++ b/docs/releases/1.8.12.txt
@@ -12,3 +12,6 @@ Bugfixes
* Made ``MultiPartParser`` ignore filenames that normalize to an empty string
to fix crash in ``MemoryFileUploadHandler`` on specially crafted user input
(:ticket:`26325`).
+
+* Fixed data loss on SQLite where ``DurationField`` values with fractional
+ seconds could be saved as ``None`` (:ticket:`26324`).
diff --git a/docs/releases/1.9.5.txt b/docs/releases/1.9.5.txt
index d14b1ac98e..55fd794d78 100644
--- a/docs/releases/1.9.5.txt
+++ b/docs/releases/1.9.5.txt
@@ -16,3 +16,6 @@ Bugfixes
* Fixed a race condition in ``BaseCache.get_or_set()`` (:ticket:`26332`). It
now returns the ``default`` value instead of ``False`` if there's an error
when trying to add the value to the cache.
+
+* Fixed data loss on SQLite where ``DurationField`` values with fractional
+ seconds could be saved as ``None`` (:ticket:`26324`).
diff --git a/tests/model_fields/test_durationfield.py b/tests/model_fields/test_durationfield.py
index fb26baadc9..82c5c875bf 100644
--- a/tests/model_fields/test_durationfield.py
+++ b/tests/model_fields/test_durationfield.py
@@ -22,6 +22,12 @@ class TestSaveLoad(TestCase):
loaded = NullDurationModel.objects.get()
self.assertEqual(loaded.field, None)
+ def test_fractional_seconds(self):
+ value = datetime.timedelta(seconds=2.05)
+ d = DurationModel.objects.create(field=value)
+ d.refresh_from_db()
+ self.assertEqual(d.field, value)
+
class TestQuerying(TestCase):