diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 99e6ceb..bdb80e8 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -17,8 +17,7 @@ master - Adds 2 settings to customize how cache keys are generated - Adds a benchmark - Adds file-based cache support for Django 1.7 -- Fixes overridden settings not working when they are already defined in - Django settings +- Simplifies cachalot_settings and forbids its modification 0.8.1 diff --git a/benchmark.py b/benchmark.py index a9dce8b..73c6718 100755 --- a/benchmark.py +++ b/benchmark.py @@ -13,12 +13,11 @@ from django.conf import settings from django.contrib.auth.models import User, Group from django.core.cache import get_cache from django.db import connections, connection -from django.test.utils import CaptureQueriesContext +from django.test.utils import CaptureQueriesContext, override_settings import matplotlib.pyplot as plt import pandas as pd from cachalot.api import invalidate_all -from cachalot.settings import cachalot_settings from cachalot.tests.models import Test @@ -71,7 +70,7 @@ class Benchmark(object): query_str = 'list(%s)' % query_str self.query_function = eval('lambda using: ' + query_str) - with cachalot_settings(CACHALOT_ENABLED=False): + with override_settings(CACHALOT_ENABLED=False): self.bench_once(CONTEXTS[0], num_queries) self.bench_once(CONTEXTS[1], num_queries, invalidate_before=True) @@ -97,7 +96,7 @@ class Benchmark(object): for cache_alias in settings.CACHES: cache = get_cache(cache_alias) self.cache_name = cache.__class__.__name__[:-5].lower() - with cachalot_settings(CACHALOT_CACHE=cache_alias): + with override_settings(CACHALOT_CACHE=cache_alias): self.execute_benchmark() self.df = pd.DataFrame.from_records(self.data) diff --git a/cachalot/settings.py b/cachalot/settings.py index d730db5..85a304a 100644 --- a/cachalot/settings.py +++ b/cachalot/settings.py @@ -1,32 +1,6 @@ -from functools import wraps from django.conf import settings -class SettingsOverrider(object): - def __init__(self, settings, overrides): - self.settings = settings - self.overrides = overrides - self.originals = [(k, getattr(settings, k)) for k in overrides] - self.overridden = set(overrides) - settings.overridden - - def __enter__(self): - self.settings.overridden.update(self.overridden) - for k, v in self.overrides.items(): - setattr(self.settings, k, v) - - def __exit__(self, exc_type, exc_val, exc_tb): - for k, v in self.originals: - setattr(self.settings, k, v) - self.settings.overridden.difference_update(self.overridden) - - def __call__(self, func): - @wraps(func) - def inner(*args, **kwargs): - with self: - return func(*args, **kwargs) - return inner - - class Settings(object): CACHALOT_ENABLED = True CACHALOT_CACHE = 'default' @@ -35,17 +9,16 @@ class Settings(object): CACHALOT_QUERY_KEYGEN = 'cachalot.utils.get_query_cache_key' CACHALOT_TABLE_KEYGEN = 'cachalot.utils.get_table_cache_key' - def __init__(self): - self.overridden = set() - def __getattribute__(self, item): - overridden = super(Settings, self).__getattribute__('overridden') - if hasattr(settings, item) and item not in overridden: + if hasattr(settings, item): return getattr(settings, item) return super(Settings, self).__getattribute__(item) - def __call__(self, **kwargs): - return SettingsOverrider(self, kwargs) + def __setattr__(self, key, value): + raise AttributeError( + "Don't modify `cachalot_settings`, use " + "`django.test.utils.override_settings` or " + "`django.conf.settings` instead.") cachalot_settings = Settings() diff --git a/cachalot/tests/settings.py b/cachalot/tests/settings.py index 3870bbe..6121a61 100644 --- a/cachalot/tests/settings.py +++ b/cachalot/tests/settings.py @@ -10,13 +10,13 @@ from django.conf import settings from django.core.cache import DEFAULT_CACHE_ALIAS from django.db import connection from django.test import TransactionTestCase +from django.test.utils import override_settings -from ..settings import cachalot_settings from .models import Test class SettingsTestCase(TransactionTestCase): - @cachalot_settings(CACHALOT_ENABLED=False) + @override_settings(CACHALOT_ENABLED=False) def test_decorator(self): with self.assertNumQueries(1): list(Test.objects.all()) @@ -36,13 +36,13 @@ class SettingsTestCase(TransactionTestCase): list(Test.objects.all()) def test_enabled(self): - with cachalot_settings(CACHALOT_ENABLED=True): + with self.settings(CACHALOT_ENABLED=True): with self.assertNumQueries(1): list(Test.objects.all()) with self.assertNumQueries(0): list(Test.objects.all()) - with cachalot_settings(CACHALOT_ENABLED=False): + with self.settings(CACHALOT_ENABLED=False): with self.assertNumQueries(1): list(Test.objects.all()) with self.assertNumQueries(1): @@ -53,7 +53,7 @@ class SettingsTestCase(TransactionTestCase): is_sqlite = connection.vendor == 'sqlite' - with cachalot_settings(CACHALOT_ENABLED=False): + with self.settings(CACHALOT_ENABLED=False): with self.assertNumQueries(2 if is_sqlite else 1): t = Test.objects.create(name='test') with self.assertNumQueries(1): @@ -63,7 +63,7 @@ class SettingsTestCase(TransactionTestCase): @skipIf(len(settings.CACHES) == 1, 'We can’t change the cache used since there’s only one configured') def test_cache(self): - with cachalot_settings(CACHALOT_CACHE=DEFAULT_CACHE_ALIAS): + with self.settings(CACHALOT_CACHE=DEFAULT_CACHE_ALIAS): with self.assertNumQueries(1): list(Test.objects.all()) with self.assertNumQueries(0): @@ -72,7 +72,7 @@ class SettingsTestCase(TransactionTestCase): other_cache_alias = [alias for alias in settings.CACHES if alias != DEFAULT_CACHE_ALIAS][0] - with cachalot_settings(CACHALOT_CACHE=other_cache_alias): + with self.settings(CACHALOT_CACHE=other_cache_alias): with self.assertNumQueries(1): list(Test.objects.all()) with self.assertNumQueries(0): @@ -84,7 +84,7 @@ class SettingsTestCase(TransactionTestCase): with self.assertNumQueries(1): list(Test.objects.order_by('?')) - with cachalot_settings(CACHALOT_CACHE_RANDOM=True): + with self.settings(CACHALOT_CACHE_RANDOM=True): with self.assertNumQueries(1): list(Test.objects.order_by('?')) with self.assertNumQueries(0): diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 1933e05..ee1588d 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -81,26 +81,21 @@ Settings Dynamic overriding ~~~~~~~~~~~~~~~~~~ -Obviously, you can set these settings in your Django settings. -But you can also change them whenever you want! -Simply use ``cachalot_settings`` as a context manager, a decorator, -or simply by changing its attributes: +Django-cachalot is built so that its settings can be dynamically changed. + +For example: .. code:: python - from cachalot.settings import cachalot_settings + from django.conf import settings + from django.test.utils import override_settings - with cachalot_settings(CACHALOT_ENABLED=False): + with override_settings(CACHALOT_ENABLED=False): # SQL queries are not cached in this block - @cachalot_settings(CACHALOT_CACHE='another_alias') + @override_settings(CACHALOT_CACHE='another_alias') def your_function(): # What’s in this function uses another cache # Globally disables SQL caching until you set it back to True - cachalot_settings.CACHALOT_ENABLED = False - -In tests, you can use -`Django’s testing tools `_ -as well as ``cachalot_settings``. The only difference is that you can’t use -``cachalot_settings`` to decorate a class. + settings.CACHALOT_ENABLED = False