From e750effa5a1b722f20ca3b514990636582dbea03 Mon Sep 17 00:00:00 2001 From: Bertrand Bordage Date: Sun, 4 Jun 2017 19:45:39 +0200 Subject: [PATCH] Allows specifying model lookups in API functions. --- cachalot/api.py | 10 +++++++--- cachalot/templatetags/cachalot.py | 13 ++----------- cachalot/tests/api.py | 25 +++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/cachalot/api.py b/cachalot/api.py index af1067c..852a90d 100644 --- a/cachalot/api.py +++ b/cachalot/api.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals +from django.apps import apps from django.conf import settings from django.db import connections from django.utils.six import string_types @@ -29,7 +30,8 @@ def _cache_db_tables_iterator(tables, cache_alias, db_alias): def _get_tables(tables_or_models): - return [o if isinstance(o, string_types) else o._meta.db_table + return [(apps.get_model(o)._meta.db_table if '.' in o else o) + if isinstance(o, string_types) else o._meta.db_table for o in tables_or_models] @@ -46,7 +48,8 @@ def invalidate(*tables_or_models, **kwargs): If ``db_alias`` is specified, it only clears the SQL queries executed on this database, otherwise queries from all databases are cleared. - :arg tables_or_models: SQL tables names or models (or combination of both) + :arg tables_or_models: SQL tables names, models or models lookups + (or a combination) :type tables_or_models: tuple of strings or models :arg cache_alias: Alias from the Django ``CACHES`` setting :type cache_alias: string or NoneType @@ -89,7 +92,8 @@ def get_last_invalidation(*tables_or_models, **kwargs): If ``db_alias`` is specified, it only fetches invalidations for this database, otherwise invalidations for all databases are fetched. - :arg tables_or_models: SQL tables names or models (or combination of both) + :arg tables_or_models: SQL tables names, models or models lookups + (or a combination) :type tables_or_models: tuple of strings or models :arg cache_alias: Alias from the Django ``CACHES`` setting :type cache_alias: string or NoneType diff --git a/cachalot/templatetags/cachalot.py b/cachalot/templatetags/cachalot.py index e900bd1..7c17b24 100644 --- a/cachalot/templatetags/cachalot.py +++ b/cachalot/templatetags/cachalot.py @@ -1,18 +1,9 @@ -from django.apps import apps from django.template import Library -from ..api import get_last_invalidation as get_last_invalidation_function +from ..api import get_last_invalidation register = Library() -@register.assignment_tag -def get_last_invalidation(*tables_or_model_lookups, **kwargs): - tables_or_models = [] - for table_or_model_lookup in tables_or_model_lookups: - if '.' in table_or_model_lookup: - tables_or_models.append(apps.get_model(table_or_model_lookup)) - else: - tables_or_models.append(table_or_model_lookup) - return get_last_invalidation_function(*tables_or_models, **kwargs) +register.assignment_tag(get_last_invalidation) diff --git a/cachalot/tests/api.py b/cachalot/tests/api.py index 6e83947..1d99968 100644 --- a/cachalot/tests/api.py +++ b/cachalot/tests/api.py @@ -46,6 +46,27 @@ class APITestCase(TestUtilsMixin, TransactionTestCase): data3 = list(Test.objects.values_list('name', flat=True)) self.assertListEqual(data3, ['test1', 'test2']) + def test_invalidate_models_lookups(self): + with self.assertNumQueries(1): + data1 = list(Test.objects.values_list('name', flat=True)) + self.assertListEqual(data1, ['test1']) + + with self.settings(CACHALOT_INVALIDATE_RAW=False): + with connection.cursor() as cursor: + cursor.execute( + "INSERT INTO cachalot_test (name, public) " + "VALUES ('test2', %s);", [1 if self.is_sqlite else True]) + + with self.assertNumQueries(0): + data2 = list(Test.objects.values_list('name', flat=True)) + self.assertListEqual(data2, ['test1']) + + invalidate('cachalot.Test') + + with self.assertNumQueries(1): + data3 = list(Test.objects.values_list('name', flat=True)) + self.assertListEqual(data3, ['test1', 'test2']) + def test_invalidate_models(self): with self.assertNumQueries(1): data1 = list(Test.objects.values_list('name', flat=True)) @@ -105,6 +126,10 @@ class APITestCase(TestUtilsMixin, TransactionTestCase): invalidate('cachalot_test') timestamp = get_last_invalidation('cachalot_test') self.assertAlmostEqual(timestamp, time(), delta=0.1) + same_timestamp = get_last_invalidation('cachalot.Test') + self.assertEqual(same_timestamp, timestamp) + same_timestamp = get_last_invalidation(Test) + self.assertEqual(same_timestamp, timestamp) timestamp = get_last_invalidation('cachalot_testparent') self.assertNotAlmostEqual(timestamp, time(), delta=0.1)