diff --git a/django/contrib/postgres/fields/ranges.py b/django/contrib/postgres/fields/ranges.py index 679e87f44e..5681c373c0 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.8.7.txt b/docs/releases/1.8.7.txt index ec9f310ad9..f73d53e799 100644 --- a/docs/releases/1.8.7.txt +++ b/docs/releases/1.8.7.txt @@ -30,3 +30,7 @@ Bugfixes * Fixed a regression in 1.8 by making ``gettext()`` once again return UTF-8 bytestrings on Python 2 if the input is a bytestring (:ticket:`25720`). + +* Fixed serialization of + :class:`~django.contrib.postgres.fields.DateRangeField` and + :class:`~django.contrib.postgres.fields.DateTimeRangeField` (:ticket:`24937`). diff --git a/tests/postgres_tests/test_ranges.py b/tests/postgres_tests/test_ranges.py index 8f7e775d21..e90c2f8709 100644 --- a/tests/postgres_tests/test_ranges.py +++ b/tests/postgres_tests/test_ranges.py @@ -195,24 +195,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(TestCase):