diff --git a/cachalot/tests/__init__.py b/cachalot/tests/__init__.py index 6b4308a..2f311e0 100644 --- a/cachalot/tests/__init__.py +++ b/cachalot/tests/__init__.py @@ -1,6 +1,4 @@ -from django import VERSION as django_version - -from .read import ReadTestCase +from .read import ReadTestCase, ParameterTypeTestCase from .write import WriteTestCase, DatabaseCommandTestCase from .transaction import AtomicTestCase from .thread_safety import ThreadSafetyTestCase @@ -8,5 +6,4 @@ from .multi_db import MultiDatabaseTestCase from .settings import SettingsTestCase from .api import APITestCase, CommandTestCase from .signals import SignalsTestCase -if django_version >= (1, 8): - from .postgres import PostgresReadTest +from .postgres import PostgresReadTest diff --git a/cachalot/tests/migrations/0001_initial.py b/cachalot/tests/migrations/0001_initial.py index 751897b..284bc18 100644 --- a/cachalot/tests/migrations/0001_initial.py +++ b/cachalot/tests/migrations/0001_initial.py @@ -25,6 +25,7 @@ class Migration(migrations.Migration): ('datetime', models.DateTimeField(null=True, blank=True)), ('owner', models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, null=True)), ('permission', models.ForeignKey(blank=True, to='auth.Permission', null=True)), + ('a_float', models.FloatField(null=True, blank=True)), ('bin', models.BinaryField(null=True, blank=True)), ('ip', models.GenericIPAddressField(null=True, blank=True)), ], diff --git a/cachalot/tests/models.py b/cachalot/tests/models.py index 34210d0..fd52fb8 100644 --- a/cachalot/tests/models.py +++ b/cachalot/tests/models.py @@ -6,7 +6,8 @@ from django import VERSION as django_version from django.conf import settings from django.db.models import ( Model, CharField, ForeignKey, BooleanField, DateField, DateTimeField, - ManyToManyField, BinaryField, IntegerField, GenericIPAddressField) + ManyToManyField, BinaryField, IntegerField, GenericIPAddressField, + FloatField) if django_version >= (1, 8): from django.db.models import DurationField, UUIDField @@ -18,6 +19,8 @@ class Test(Model): date = DateField(null=True, blank=True) datetime = DateTimeField(null=True, blank=True) permission = ForeignKey('auth.Permission', null=True, blank=True) + + a_float = FloatField(null=True, blank=True) bin = BinaryField(null=True, blank=True) ip = GenericIPAddressField(null=True, blank=True) if django_version >= (1, 8): diff --git a/cachalot/tests/postgres.py b/cachalot/tests/postgres.py index 13f0083..d1a5698 100644 --- a/cachalot/tests/postgres.py +++ b/cachalot/tests/postgres.py @@ -11,10 +11,11 @@ from django.core.cache import caches from django.core.cache.backends.filebased import FileBasedCache from django.db import connection from django.test import TransactionTestCase, override_settings -from psycopg2._range import NumericRange, DateRange, DateTimeTZRange +from psycopg2.extras import NumericRange, DateRange, DateTimeTZRange from pytz import timezone -from .models import PostgresModel, Test +if django_version[:2] >= (1, 8): + from .models import PostgresModel, Test @skipUnless(connection.vendor == 'postgresql' and django_version[:2] >= (1, 8), diff --git a/cachalot/tests/read.py b/cachalot/tests/read.py index f4985e1..a96011f 100644 --- a/cachalot/tests/read.py +++ b/cachalot/tests/read.py @@ -681,6 +681,15 @@ class ReadTestCase(TransactionTestCase): with connection.cursor() as cursor: cursor.execute('DROP TABLE %s;' % table_name) + +class ParameterTypeTestCase(TransactionTestCase): + def setUp(self): + self.is_sqlite = connection.vendor == 'sqlite' + if connection.vendor == 'mysql': + # We need to reopen the connection or Django + # will execute an extra SQL request below. + connection.cursor() + def test_unknown_parameter_type(self): """ Tests if queries with an unknown parameter type are not cached. @@ -713,11 +722,30 @@ class ReadTestCase(TransactionTestCase): with self.assertNumQueries(0 if is_mysql else 1): list(Test.objects.filter(bin=b'def')) + def test_float(self): + with self.assertNumQueries(2 if self.is_sqlite else 1): + Test.objects.create(name='test1', a_float=0.123456789) + with self.assertNumQueries(2 if self.is_sqlite else 1): + Test.objects.create(name='test2', a_float=12345.6789) + with self.assertNumQueries(1): + data1 = list(Test.objects.values_list('a_float', flat=True).filter( + a_float__isnull=False).order_by('a_float')) + with self.assertNumQueries(0): + data2 = list(Test.objects.values_list('a_float', flat=True).filter( + a_float__isnull=False).order_by('a_float')) + self.assertListEqual(data2, data1) + self.assertListEqual(data2, [0.123456789, 12345.6789]) + + with self.assertNumQueries(1): + Test.objects.get(a_float=0.123456789) + with self.assertNumQueries(0): + Test.objects.get(a_float=0.123456789) + def test_ipv4_address(self): with self.assertNumQueries(2 if self.is_sqlite else 1): - Test.objects.create(name='test3', ip='127.0.0.1') + Test.objects.create(name='test1', ip='127.0.0.1') with self.assertNumQueries(2 if self.is_sqlite else 1): - Test.objects.create(name='test4', ip='192.168.0.1') + Test.objects.create(name='test2', ip='192.168.0.1') with self.assertNumQueries(1): data1 = list(Test.objects.values_list('ip', flat=True).filter( ip__isnull=False).order_by('ip')) @@ -734,9 +762,9 @@ class ReadTestCase(TransactionTestCase): def test_ipv6_address(self): with self.assertNumQueries(2 if self.is_sqlite else 1): - Test.objects.create(name='test3', ip='2001:db8:a0b:12f0::1/64') + Test.objects.create(name='test1', ip='2001:db8:a0b:12f0::1/64') with self.assertNumQueries(2 if self.is_sqlite else 1): - Test.objects.create(name='test4', ip='2001:db8:0:85a3::ac1f:8001') + Test.objects.create(name='test2', ip='2001:db8:0:85a3::ac1f:8001') with self.assertNumQueries(1): data1 = list(Test.objects.values_list('ip', flat=True).filter( ip__isnull=False).order_by('ip')) @@ -756,9 +784,9 @@ class ReadTestCase(TransactionTestCase): 'DurationField is not available in Django 1.7') def test_duration(self): with self.assertNumQueries(2 if self.is_sqlite else 1): - Test.objects.create(name='test3', duration=datetime.timedelta(30)) + Test.objects.create(name='test1', duration=datetime.timedelta(30)) with self.assertNumQueries(2 if self.is_sqlite else 1): - Test.objects.create(name='test4', duration=datetime.timedelta(60)) + Test.objects.create(name='test2', duration=datetime.timedelta(60)) with self.assertNumQueries(1): data1 = list(Test.objects.values_list( 'duration', flat=True).filter( @@ -780,10 +808,10 @@ class ReadTestCase(TransactionTestCase): 'UUIDField is not available in Django 1.7') def test_uuid(self): with self.assertNumQueries(2 if self.is_sqlite else 1): - Test.objects.create(name='test3', + Test.objects.create(name='test1', uuid='1cc401b7-09f4-4520-b8d0-c267576d196b') with self.assertNumQueries(2 if self.is_sqlite else 1): - Test.objects.create(name='test4', + Test.objects.create(name='test2', uuid='ebb3b6e1-1737-4321-93e3-4c35d61ff491') with self.assertNumQueries(1): data1 = list(Test.objects.values_list( diff --git a/cachalot/utils.py b/cachalot/utils.py index 0f61cbc..e998dcc 100644 --- a/cachalot/utils.py +++ b/cachalot/utils.py @@ -22,7 +22,7 @@ class UncachableQuery(Exception): CACHABLE_PARAM_TYPES = { - bool, int, binary_type, text_type, type(None), + bool, int, float, binary_type, text_type, type(None), datetime.date, datetime.time, datetime.datetime, datetime.timedelta, UUID, }