From 9cf0cd318a3f46bb632c6bbfc61a0029ce6a42ec Mon Sep 17 00:00:00 2001 From: Bertrand Bordage Date: Wed, 28 Oct 2015 16:19:33 +0100 Subject: [PATCH] Adds tests for UUIDField and DurationField and cache their queries. --- cachalot/tests/migrations/0001_initial.py | 4 ++ cachalot/tests/models.py | 5 ++ cachalot/tests/read.py | 69 +++++++++++++++++++---- cachalot/utils.py | 3 +- 4 files changed, 68 insertions(+), 13 deletions(-) diff --git a/cachalot/tests/migrations/0001_initial.py b/cachalot/tests/migrations/0001_initial.py index fd1bd5d..751897b 100644 --- a/cachalot/tests/migrations/0001_initial.py +++ b/cachalot/tests/migrations/0001_initial.py @@ -56,6 +56,10 @@ if django_version >= (1, 8): IntegerRangeField, FloatRangeField, DateRangeField, DateTimeRangeField) Migration.operations.extend(( + migrations.AddField('Test', 'duration', + models.DurationField(null=True, blank=True)), + migrations.AddField('Test', 'uuid', + models.UUIDField(null=True, blank=True)), migrations.RunSQL('CREATE EXTENSION hstore;', hints={'extension': 'hstore'}), migrations.RunSQL('CREATE EXTENSION unaccent;', diff --git a/cachalot/tests/models.py b/cachalot/tests/models.py index 62a21a8..34210d0 100644 --- a/cachalot/tests/models.py +++ b/cachalot/tests/models.py @@ -7,6 +7,8 @@ from django.conf import settings from django.db.models import ( Model, CharField, ForeignKey, BooleanField, DateField, DateTimeField, ManyToManyField, BinaryField, IntegerField, GenericIPAddressField) +if django_version >= (1, 8): + from django.db.models import DurationField, UUIDField class Test(Model): @@ -18,6 +20,9 @@ class Test(Model): permission = ForeignKey('auth.Permission', null=True, blank=True) bin = BinaryField(null=True, blank=True) ip = GenericIPAddressField(null=True, blank=True) + if django_version >= (1, 8): + duration = DurationField(null=True, blank=True) + uuid = UUIDField(null=True, blank=True) class Meta(object): ordering = ('name',) diff --git a/cachalot/tests/read.py b/cachalot/tests/read.py index 84fd69a..f4985e1 100644 --- a/cachalot/tests/read.py +++ b/cachalot/tests/read.py @@ -3,7 +3,9 @@ from __future__ import unicode_literals import datetime from unittest import skipIf +from uuid import UUID +from django import VERSION as django_version from django.contrib.auth.models import Group, Permission, User from django.contrib.contenttypes.models import ContentType from django.core.cache import cache @@ -712,10 +714,6 @@ class ReadTestCase(TransactionTestCase): list(Test.objects.filter(bin=b'def')) def test_ipv4_address(self): - with self.assertNumQueries(1): - list(Test.objects.values('ip')) - with self.assertNumQueries(0): - list(Test.objects.values('ip')) with self.assertNumQueries(2 if self.is_sqlite else 1): Test.objects.create(name='test3', ip='127.0.0.1') with self.assertNumQueries(2 if self.is_sqlite else 1): @@ -730,15 +728,11 @@ class ReadTestCase(TransactionTestCase): self.assertListEqual(data2, ['127.0.0.1', '192.168.0.1']) with self.assertNumQueries(1): - list(Test.objects.filter(ip='127.0.0.1')) + Test.objects.get(ip='127.0.0.1') with self.assertNumQueries(0): - list(Test.objects.filter(ip='127.0.0.1')) + Test.objects.get(ip='127.0.0.1') def test_ipv6_address(self): - with self.assertNumQueries(1): - list(Test.objects.values('ip')) - with self.assertNumQueries(0): - list(Test.objects.values('ip')) with self.assertNumQueries(2 if self.is_sqlite else 1): Test.objects.create(name='test3', ip='2001:db8:a0b:12f0::1/64') with self.assertNumQueries(2 if self.is_sqlite else 1): @@ -754,6 +748,57 @@ class ReadTestCase(TransactionTestCase): '2001:db8:0:85a3::ac1f:8001', '2001:db8:a0b:12f0::1/64']) with self.assertNumQueries(1): - list(Test.objects.filter(ip='2001:db8:0:85a3::ac1f:8001')) + Test.objects.get(ip='2001:db8:0:85a3::ac1f:8001') with self.assertNumQueries(0): - list(Test.objects.filter(ip='2001:db8:0:85a3::ac1f:8001')) + Test.objects.get(ip='2001:db8:0:85a3::ac1f:8001') + + @skipIf(django_version[2:] == (1, 7), + '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)) + with self.assertNumQueries(2 if self.is_sqlite else 1): + Test.objects.create(name='test4', duration=datetime.timedelta(60)) + with self.assertNumQueries(1): + data1 = list(Test.objects.values_list( + 'duration', flat=True).filter( + duration__isnull=False).order_by('duration')) + with self.assertNumQueries(0): + data2 = list(Test.objects.values_list( + 'duration', flat=True).filter( + duration__isnull=False).order_by('duration')) + self.assertListEqual(data2, data1) + self.assertListEqual(data2, [ + datetime.timedelta(30), datetime.timedelta(60)]) + + with self.assertNumQueries(1): + Test.objects.get(duration=datetime.timedelta(30)) + with self.assertNumQueries(0): + Test.objects.get(duration=datetime.timedelta(30)) + + @skipIf(django_version[2:] == (1, 7), + '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', + uuid='1cc401b7-09f4-4520-b8d0-c267576d196b') + with self.assertNumQueries(2 if self.is_sqlite else 1): + Test.objects.create(name='test4', + uuid='ebb3b6e1-1737-4321-93e3-4c35d61ff491') + with self.assertNumQueries(1): + data1 = list(Test.objects.values_list( + 'uuid', flat=True).filter( + uuid__isnull=False).order_by('uuid')) + with self.assertNumQueries(0): + data2 = list(Test.objects.values_list( + 'uuid', flat=True).filter( + uuid__isnull=False).order_by('uuid')) + self.assertListEqual(data2, data1) + self.assertListEqual(data2, [ + UUID('1cc401b7-09f4-4520-b8d0-c267576d196b'), + UUID('ebb3b6e1-1737-4321-93e3-4c35d61ff491')]) + + with self.assertNumQueries(1): + Test.objects.get(uuid=UUID('1cc401b7-09f4-4520-b8d0-c267576d196b')) + with self.assertNumQueries(0): + Test.objects.get(uuid=UUID('1cc401b7-09f4-4520-b8d0-c267576d196b')) diff --git a/cachalot/utils.py b/cachalot/utils.py index 3927b70..0f61cbc 100644 --- a/cachalot/utils.py +++ b/cachalot/utils.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals import datetime from hashlib import sha1 from time import time +from uuid import UUID from django.db import connections from django.db.models.sql import Query @@ -22,7 +23,7 @@ class UncachableQuery(Exception): CACHABLE_PARAM_TYPES = { bool, int, binary_type, text_type, type(None), - datetime.date, datetime.time, datetime.datetime, datetime.timedelta, + datetime.date, datetime.time, datetime.datetime, datetime.timedelta, UUID, } try: