From 80616c4e80ee1993f4dfa67b4641ac28340d1ee3 Mon Sep 17 00:00:00 2001 From: Paulo Giacomelli Date: Wed, 9 Oct 2024 15:12:59 -0600 Subject: [PATCH] Allow to disable cache on field level --- dbsettings/loading.py | 10 ++++++---- dbsettings/values.py | 10 +++++++++- tests/models.py | 2 +- tests/tests.py | 18 ++++++++++++------ 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/dbsettings/loading.py b/dbsettings/loading.py index fd78cd7..3a7bcd8 100644 --- a/dbsettings/loading.py +++ b/dbsettings/loading.py @@ -39,7 +39,10 @@ def get_setting_storage(module_name, class_name, attribute_name): from dbsettings.models import Setting from dbsettings.settings import USE_CACHE, CACHE_EXPIRATION storage = None - if USE_CACHE: + setting_object = get_setting(module_name, class_name, attribute_name) + can_cache = USE_CACHE and not setting_object.disable_cache + + if can_cache: key = _get_cache_key(module_name, class_name, attribute_name) try: storage = cache.get(key) @@ -53,14 +56,13 @@ def get_setting_storage(module_name, class_name, attribute_name): attribute_name=attribute_name, ) except Setting.DoesNotExist: - setting_object = get_setting(module_name, class_name, attribute_name) storage = Setting( module_name=module_name, class_name=class_name, attribute_name=attribute_name, value=setting_object.default, ) - if USE_CACHE: + if can_cache: try: args = [] if CACHE_EXPIRATION != -1: @@ -88,6 +90,6 @@ def set_setting_value(module_name, class_name, attribute_name, value): storage.value = setting.get_db_prep_save(value, oldvalue=storage.value) storage.save() setting_changed.send(sender=setting, value=setting.to_python(value)) - if USE_CACHE: + if USE_CACHE and not setting.disable_cache: key = _get_cache_key(module_name, class_name, attribute_name) cache.delete(key) diff --git a/dbsettings/values.py b/dbsettings/values.py index 8a74c06..869107f 100644 --- a/dbsettings/values.py +++ b/dbsettings/values.py @@ -29,12 +29,20 @@ class Value(object): creation_counter = 0 unitialized_value = None - def __init__(self, description=None, help_text=None, choices=None, required=True, default=None, widget=None): + def __init__(self, + description=None, + help_text=None, + choices=None, + required=True, + default=None, + widget=None, + disable_cache=False): self.description = description self.help_text = help_text self.choices = choices or [] self.required = required self.widget = widget + self.disable_cache = disable_cache if default is None: self.default = self.unitialized_value else: diff --git a/tests/models.py b/tests/models.py index 9812e3f..9c5ecdc 100644 --- a/tests/models.py +++ b/tests/models.py @@ -14,7 +14,7 @@ class TestSettings(dbsettings.Group): time = dbsettings.TimeValue() datetime = dbsettings.DateTimeValue() string_choices = dbsettings.StringValue(choices=(("String1", "First String Choice"), ("String2", "Second String Choice"))) - + no_caching_string = dbsettings.StringValue(disable_cache=True) class Defaults(models.Model): class settings(dbsettings.Group): diff --git a/tests/tests.py b/tests/tests.py index 81f4d81..3baa2b6 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -53,6 +53,7 @@ def setUp(self): loading.set_setting_value(MODULE_NAME, 'Populated', 'time', '16:19:17') loading.set_setting_value(MODULE_NAME, 'Populated', 'datetime', '2012-06-28 16:19:17') loading.set_setting_value(MODULE_NAME, 'Populated', 'string_choices', 'String1') + loading.set_setting_value(MODULE_NAME, 'Populated', 'no_caching_string', 'Populated: Not Cached String') loading.set_setting_value(MODULE_NAME, '', 'boolean', False) loading.set_setting_value(MODULE_NAME, '', 'integer', 14) loading.set_setting_value(MODULE_NAME, '', 'string', 'Module') @@ -73,6 +74,7 @@ def setUp(self): loading.set_setting_value(MODULE_NAME, 'Combined', 'time', '14:17:15') loading.set_setting_value(MODULE_NAME, 'Combined', 'datetime', '2010-04-26 14:17:15') loading.set_setting_value(MODULE_NAME, 'Combined', 'string_choices', 'String1') + loading.set_setting_value(MODULE_NAME, 'Combined', 'no_caching_string', 'Combined: Not Cached String') loading.set_setting_value(MODULE_NAME, 'Combined', 'enabled', True) def test_settings(self): @@ -89,6 +91,7 @@ def test_settings(self): self.assertEqual(Populated.settings.datetime, datetime.datetime(2012, 6, 28, 16, 19, 17)) self.assertEqual(Populated.settings.string_choices, "String1") self.assertEqual(Populated.settings.get_string_choices_display(), "First String Choice") + self.assertEqual(Populated.settings.no_caching_string, "Populated: Not Cached String") # Module settings are kept separate from model settings self.assertEqual(module_settings.boolean, False) @@ -112,7 +115,7 @@ def test_settings(self): self.assertEqual(Combined.settings.datetime, datetime.datetime(2010, 4, 26, 14, 17, 15)) self.assertEqual(Combined.settings.string_choices, "String1") self.assertEqual(Combined.settings.get_string_choices_display(), "First String Choice") - + self.assertEqual(Combined.settings.no_caching_string, "Combined: Not Cached String") # Settings not in the database use empty defaults self.assertEqual(Unpopulated.settings.boolean, False) @@ -137,10 +140,10 @@ def test_settings(self): # Settings should be retrieved in the order of definition self.assertEqual(Populated.settings.keys(), ['boolean', 'integer', 'string', 'list_semi_colon', - 'list_comma', 'date', 'time', 'datetime', 'string_choices']) + 'list_comma', 'date', 'time', 'datetime', 'string_choices', 'no_caching_string',]) self.assertEqual(Combined.settings.keys(), ['boolean', 'integer', 'string', 'list_semi_colon', - 'list_comma', 'date', 'time', 'datetime', 'string_choices', 'enabled']) + 'list_comma', 'date', 'time', 'datetime', 'string_choices', 'no_caching_string', 'enabled',]) # Values should be coerced to the proper Python types self.assertTrue(isinstance(Populated.settings.boolean, bool)) @@ -166,6 +169,7 @@ def test_settings(self): datetime.time(1, 2, 3)) loading.set_setting_value(MODULE_NAME, 'Unpopulated', 'datetime', datetime.datetime(1912, 6, 23, 1, 2, 3)) + loading.set_setting_value(MODULE_NAME, "Unpopulated", "no_caching_string", "Unpopulated: Not Cached String") self.assertEqual(Unpopulated.settings.boolean, True) self.assertEqual(Unpopulated.settings.integer, 13) @@ -175,6 +179,7 @@ def test_settings(self): self.assertEqual(Unpopulated.settings.date, datetime.date(1912, 6, 23)) self.assertEqual(Unpopulated.settings.time, datetime.time(1, 2, 3)) self.assertEqual(Unpopulated.settings.datetime, datetime.datetime(1912, 6, 23, 1, 2, 3)) + self.assertEqual(Unpopulated.settings.no_caching_string, "Unpopulated: Not Cached String") # Updating settings with defaults loading.set_setting_value(MODULE_NAME, 'Defaults', 'boolean', False) @@ -329,6 +334,7 @@ def test_forms(self): '%s__Editable__time' % MODULE_NAME: '16:37:45', '%s__Editable__datetime' % MODULE_NAME: '2012-06-28 16:37:45', '%s__Editable__string_choices' % MODULE_NAME: 'String1', + '%s__Editable__no_caching_string' % MODULE_NAME: 'Get my string!', } response = self.client.post(site_form, data) self.assertRedirects(response, site_form) @@ -361,15 +367,15 @@ def test_forms(self): user.user_permissions.remove(perm) # Check if module level settings show properly - self._test_form_fields(site_form, 9, False) + self._test_form_fields(site_form, 10, False) # Add perm for whole app perm = Permission.objects.get(codename='can_edit__settings') # module-level settings user.user_permissions.add(perm) - self._test_form_fields(site_form, 20) + self._test_form_fields(site_form, 22) # Remove other perms - left only global perm perm = Permission.objects.get(codename='can_edit_editable_settings') user.user_permissions.remove(perm) - self._test_form_fields(site_form, 11) + self._test_form_fields(site_form, 12) def _test_form_fields(self, url, fields_num, present=True, variable_name='form'): global_setting = '%s____clash2' % MODULE_NAME # Some global setting name