Skip to content

Commit

Permalink
Add support for caching queries with enum filters (#267)
Browse files Browse the repository at this point in the history
  • Loading branch information
danlamanna authored Nov 4, 2024
1 parent 2a36305 commit d4985ff
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 2 deletions.
2 changes: 2 additions & 0 deletions cachalot/tests/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class Migration(migrations.Migration):
('permission', models.ForeignKey(blank=True, to='auth.Permission', null=True, on_delete=models.PROTECT)),
('a_float', models.FloatField(null=True, blank=True)),
('a_decimal', models.DecimalField(null=True, blank=True, max_digits=5, decimal_places=2)),
('a_choice', models.CharField(choices=[("foo","foo"), ("bar","bar")], null=True, max_length=3)),
('a_dict_choice', models.CharField(choices=[("foo","foo"), ("bar","bar")], null=True, max_length=3)),
('bin', models.BinaryField(null=True, blank=True)),
('ip', models.GenericIPAddressField(null=True, blank=True)),
('duration', models.DurationField(null=True, blank=True)),
Expand Down
7 changes: 6 additions & 1 deletion cachalot/tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@
DateTimeRangeField)
from django.db.models import (
Model, CharField, ForeignKey, BooleanField, DateField, DateTimeField,
ManyToManyField, BinaryField, IntegerField, GenericIPAddressField,
ManyToManyField, BinaryField, IntegerField, GenericIPAddressField, TextChoices,
FloatField, DecimalField, DurationField, UUIDField, SET_NULL, PROTECT)


class SomeChoices(TextChoices):
foo = 'foo'
bar = 'bar'

class Test(Model):
name = CharField(max_length=20)
owner = ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True,
Expand All @@ -25,6 +29,7 @@ class Test(Model):
a_float = FloatField(null=True, blank=True)
a_decimal = DecimalField(null=True, blank=True,
max_digits=5, decimal_places=2)
a_choice = CharField(max_length=3, choices=SomeChoices.choices, null=True)
bin = BinaryField(null=True, blank=True)
ip = GenericIPAddressField(null=True, blank=True)
duration = DurationField(null=True, blank=True)
Expand Down
7 changes: 6 additions & 1 deletion cachalot/tests/read.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from cachalot.cache import cachalot_caches
from ..settings import cachalot_settings
from ..utils import UncachableQuery
from .models import Test, TestChild, TestParent, UnmanagedModel
from .models import SomeChoices, Test, TestChild, TestParent, UnmanagedModel
from .test_utils import TestUtilsMixin, FilteredTransactionTestCase

from .tests_decorators import all_final_sql_checks, with_final_sql_check, no_final_sql_check
Expand Down Expand Up @@ -243,6 +243,11 @@ def test_distinct(self):
Permission, ContentType)
self.assert_query_cached(qs, [self.t1])

def test_django_enums(self):
t = Test.objects.create(name='test1', a_choice=SomeChoices.foo)
qs = Test.objects.filter(a_choice=SomeChoices.foo)
self.assert_query_cached(qs, [t])

def test_iterator(self):
with self.assertNumQueries(1):
data1 = list(Test.objects.iterator())
Expand Down
6 changes: 6 additions & 0 deletions cachalot/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from django.contrib.postgres.functions import TransactionNow
from django.db.models import Exists, QuerySet, Subquery
from django.db.models.enums import Choices
from django.db.models.expressions import RawSQL
from django.db.models.functions import Now
from django.db.models.sql import Query, AggregateQuery
Expand Down Expand Up @@ -80,6 +81,11 @@ def check_parameter_types(params):
check_parameter_types(p)
elif cl is dict:
check_parameter_types(p.items())
elif issubclass(cl, Choices):
# Handle the case where a parameter from a Choices field is passed.
# Django Choices use enum.unique() so the values are guaranteed to be unique.
# Dereference the true "value" and verify that it is cachable.
check_parameter_types([p.value])
else:
raise UncachableQuery

Expand Down

0 comments on commit d4985ff

Please sign in to comment.