summaryrefslogtreecommitdiff
path: root/tests/postgres_tests
diff options
context:
space:
mode:
authorMarc Tamlyn <marc.tamlyn@gmail.com>2015-01-10 18:13:28 +0000
committerTim Graham <timograham@gmail.com>2015-01-16 16:15:16 -0500
commit39d95fb6ada99c59d47fa0eae6d3128abafe2d58 (patch)
treef514f85027835d6504a80982184467c41da601c7 /tests/postgres_tests
parenta17724b791275578334bcdc66b3a8113eb86605e (diff)
Fixed #24092 -- Widened base field support for ArrayField.
Several issues resolved here, following from a report that a base_field of GenericIpAddressField was failing. We were using get_prep_value instead of get_db_prep_value in ArrayField which was bypassing any extra modifications to the value being made in the base field's get_db_prep_value. Changing this broke datetime support, so the postgres backend has gained the relevant operation methods to send dates/times/datetimes directly to the db backend instead of casting them to strings. Similarly, a new database feature has been added allowing the uuid to be passed directly to the backend, as we do with timedeltas. On the other side, psycopg2 expects an Inet() instance for IP address fields, so we add a value_to_db_ipaddress method to wrap the strings on postgres. We also have to manually add a database adapter to psycopg2, as we do not wish to use the built in adapter which would turn everything into Inet() instances. Thanks to smclenithan for the report.
Diffstat (limited to 'tests/postgres_tests')
-rw-r--r--tests/postgres_tests/migrations/0002_create_test_models.py16
-rw-r--r--tests/postgres_tests/models.py10
-rw-r--r--tests/postgres_tests/test_array.py30
3 files changed, 51 insertions, 5 deletions
diff --git a/tests/postgres_tests/migrations/0002_create_test_models.py b/tests/postgres_tests/migrations/0002_create_test_models.py
index bdde4a9bf6..841953d351 100644
--- a/tests/postgres_tests/migrations/0002_create_test_models.py
+++ b/tests/postgres_tests/migrations/0002_create_test_models.py
@@ -27,7 +27,9 @@ class Migration(migrations.Migration):
name='DateTimeArrayModel',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('field', django.contrib.postgres.fields.ArrayField(models.DateTimeField(), size=None)),
+ ('datetimes', django.contrib.postgres.fields.ArrayField(models.DateTimeField(), size=None)),
+ ('dates', django.contrib.postgres.fields.ArrayField(models.DateField(), size=None)),
+ ('times', django.contrib.postgres.fields.ArrayField(models.TimeField(), size=None)),
],
options={
},
@@ -44,6 +46,18 @@ class Migration(migrations.Migration):
bases=(models.Model,),
),
migrations.CreateModel(
+ name='OtherTypesArrayModel',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('ips', django.contrib.postgres.fields.ArrayField(models.GenericIPAddressField(), size=None)),
+ ('uuids', django.contrib.postgres.fields.ArrayField(models.UUIDField(), size=None)),
+ ('decimals', django.contrib.postgres.fields.ArrayField(models.DecimalField(max_digits=5, decimal_places=2), size=None)),
+ ],
+ options={
+ },
+ bases=(models.Model,),
+ ),
+ migrations.CreateModel(
name='IntegerArrayModel',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
diff --git a/tests/postgres_tests/models.py b/tests/postgres_tests/models.py
index 74af39dd04..0422aba6a0 100644
--- a/tests/postgres_tests/models.py
+++ b/tests/postgres_tests/models.py
@@ -18,13 +18,21 @@ class CharArrayModel(models.Model):
class DateTimeArrayModel(models.Model):
- field = ArrayField(models.DateTimeField())
+ datetimes = ArrayField(models.DateTimeField())
+ dates = ArrayField(models.DateField())
+ times = ArrayField(models.TimeField())
class NestedIntegerArrayModel(models.Model):
field = ArrayField(ArrayField(models.IntegerField()))
+class OtherTypesArrayModel(models.Model):
+ ips = ArrayField(models.GenericIPAddressField())
+ uuids = ArrayField(models.UUIDField())
+ decimals = ArrayField(models.DecimalField(max_digits=5, decimal_places=2))
+
+
class HStoreModel(models.Model):
field = HStoreField(blank=True, null=True)
diff --git a/tests/postgres_tests/test_array.py b/tests/postgres_tests/test_array.py
index 90f4c246c6..5c300f7ea3 100644
--- a/tests/postgres_tests/test_array.py
+++ b/tests/postgres_tests/test_array.py
@@ -1,5 +1,7 @@
+import decimal
import json
import unittest
+import uuid
from django.contrib.postgres.fields import ArrayField
from django.contrib.postgres.forms import SimpleArrayField, SplitArrayField
@@ -10,7 +12,11 @@ from django import forms
from django.test import TestCase, override_settings
from django.utils import timezone
-from .models import IntegerArrayModel, NullableIntegerArrayModel, CharArrayModel, DateTimeArrayModel, NestedIntegerArrayModel, ArrayFieldSubclass
+from .models import (
+ IntegerArrayModel, NullableIntegerArrayModel, CharArrayModel,
+ DateTimeArrayModel, NestedIntegerArrayModel, OtherTypesArrayModel,
+ ArrayFieldSubclass,
+)
@unittest.skipUnless(connection.vendor == 'postgresql', 'PostgreSQL required')
@@ -29,10 +35,16 @@ class TestSaveLoad(TestCase):
self.assertEqual(instance.field, loaded.field)
def test_dates(self):
- instance = DateTimeArrayModel(field=[timezone.now()])
+ instance = DateTimeArrayModel(
+ datetimes=[timezone.now()],
+ dates=[timezone.now().date()],
+ times=[timezone.now().time()],
+ )
instance.save()
loaded = DateTimeArrayModel.objects.get()
- self.assertEqual(instance.field, loaded.field)
+ self.assertEqual(instance.datetimes, loaded.datetimes)
+ self.assertEqual(instance.dates, loaded.dates)
+ self.assertEqual(instance.times, loaded.times)
def test_tuples(self):
instance = IntegerArrayModel(field=(1,))
@@ -70,6 +82,18 @@ class TestSaveLoad(TestCase):
loaded = NestedIntegerArrayModel.objects.get()
self.assertEqual(instance.field, loaded.field)
+ def test_other_array_types(self):
+ instance = OtherTypesArrayModel(
+ ips=['192.168.0.1', '::1'],
+ uuids=[uuid.uuid4()],
+ decimals=[decimal.Decimal(1.25), 1.75],
+ )
+ instance.save()
+ loaded = OtherTypesArrayModel.objects.get()
+ self.assertEqual(instance.ips, loaded.ips)
+ self.assertEqual(instance.uuids, loaded.uuids)
+ self.assertEqual(instance.decimals, loaded.decimals)
+
@unittest.skipUnless(connection.vendor == 'postgresql', 'PostgreSQL required')
class TestQuerying(TestCase):