Allows specifying model lookups in API functions.

This commit is contained in:
Bertrand Bordage 2017-06-04 19:45:39 +02:00
parent 95d2918612
commit e750effa5a
3 changed files with 34 additions and 14 deletions

View File

@ -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

View File

@ -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)

View File

@ -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)