Commit 2926559c authored by Matthew Somerville's avatar Matthew Somerville
Browse files

Fixed #24937 -- fix serialization of Date(Time)RangeField.

Use the DjangoJSONEncoder so that datetime and date are encoded
appropriately.
parent 0a899157
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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)
+4 −0
Original line number Diff line number Diff line
@@ -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`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

+16 −5
Original line number Diff line number Diff line
@@ -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):