From 2926559cce34e48efb4b073721926d737e372dd3 Mon Sep 17 00:00:00 2001
From: Matthew Somerville <matthew-github@dracos.co.uk>
Date: Fri, 5 Jun 2015 21:56:00 +0100
Subject: [PATCH] Fixed #24937 -- fix serialization of Date(Time)RangeField.

Use the DjangoJSONEncoder so that datetime and date are encoded
appropriately.
---
 django/contrib/postgres/fields/ranges.py |  3 ++-
 docs/releases/1.9.txt                    |  4 ++++
 tests/postgres_tests/test_ranges.py      | 21 ++++++++++++++++-----
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/django/contrib/postgres/fields/ranges.py b/django/contrib/postgres/fields/ranges.py
index 6e0f8e2284..81c04eab92 100644
--- a/django/contrib/postgres/fields/ranges.py
+++ b/django/contrib/postgres/fields/ranges.py
@@ -3,6 +3,7 @@ import json
 from psycopg2.extras import DateRange, DateTimeTZRange, NumericRange, Range
 
 from django.contrib.postgres import forms, lookups
+from django.core.serializers.json import DjangoJSONEncoder
 from django.db import models
 from django.utils import six
 
@@ -41,7 +42,7 @@ class RangeField(models.Field):
             "lower": value.lower,
             "upper": value.upper,
             "bounds": value._bounds,
-        })
+        }, cls=DjangoJSONEncoder)
 
     def formfield(self, **kwargs):
         kwargs.setdefault('form_class', self.form_field)
diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt
index 793dcd6a82..c6467d9f65 100644
--- a/docs/releases/1.9.txt
+++ b/docs/releases/1.9.txt
@@ -102,6 +102,10 @@ Minor features
 * Added :class:`~django.contrib.postgres.fields.JSONField`.
 * Added :doc:`/ref/contrib/postgres/aggregates`.
 
+* Fixed serialization of
+  :class:`~django.contrib.postgres.fields.DateRangeField` and
+  :class:`~django.contrib.postgres.fields.DateTimeRangeField`.
+
 :mod:`django.contrib.redirects`
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/tests/postgres_tests/test_ranges.py b/tests/postgres_tests/test_ranges.py
index 2461130b35..eca22c17f5 100644
--- a/tests/postgres_tests/test_ranges.py
+++ b/tests/postgres_tests/test_ranges.py
@@ -293,24 +293,35 @@ class TestSerialization(TestCase):
     test_data = (
         '[{"fields": {"ints": "{\\"upper\\": 10, \\"lower\\": 0, '
         '\\"bounds\\": \\"[)\\"}", "floats": "{\\"empty\\": true}", '
-        '"bigints": null, "timestamps": null, "dates": null}, '
+        '"bigints": null, "timestamps": "{\\"upper\\": \\"2014-02-02T12:12:12\\", '
+        '\\"lower\\": \\"2014-01-01T00:00:00\\", \\"bounds\\": \\"[)\\"}", '
+        '"dates": "{\\"upper\\": \\"2014-02-02\\", \\"lower\\": \\"2014-01-01\\", \\"bounds\\": \\"[)\\"}" }, '
         '"model": "postgres_tests.rangesmodel", "pk": null}]'
     )
 
+    lower_date = datetime.date(2014, 1, 1)
+    upper_date = datetime.date(2014, 2, 2)
+    lower_dt = datetime.datetime(2014, 1, 1, 0, 0, 0)
+    upper_dt = datetime.datetime(2014, 2, 2, 12, 12, 12)
+
     def test_dumping(self):
-        instance = RangesModel(ints=NumericRange(0, 10), floats=NumericRange(empty=True))
+        instance = RangesModel(ints=NumericRange(0, 10), floats=NumericRange(empty=True),
+            timestamps=DateTimeTZRange(self.lower_dt, self.upper_dt),
+            dates=DateRange(self.lower_date, self.upper_date))
         data = serializers.serialize('json', [instance])
         dumped = json.loads(data)
-        dumped[0]['fields']['ints'] = json.loads(dumped[0]['fields']['ints'])
+        for field in ('ints', 'dates', 'timestamps'):
+            dumped[0]['fields'][field] = json.loads(dumped[0]['fields'][field])
         check = json.loads(self.test_data)
-        check[0]['fields']['ints'] = json.loads(check[0]['fields']['ints'])
+        for field in ('ints', 'dates', 'timestamps'):
+            check[0]['fields'][field] = json.loads(check[0]['fields'][field])
         self.assertEqual(dumped, check)
 
     def test_loading(self):
         instance = list(serializers.deserialize('json', self.test_data))[0].object
         self.assertEqual(instance.ints, NumericRange(0, 10))
         self.assertEqual(instance.floats, NumericRange(empty=True))
-        self.assertEqual(instance.dates, None)
+        self.assertEqual(instance.bigints, None)
 
 
 class TestValidators(PostgreSQLTestCase):