diff --git a/constance/utils.py b/constance/utils.py index ffa98ef..229d62c 100644 --- a/constance/utils.py +++ b/constance/utils.py @@ -20,3 +20,27 @@ def get_values(): default_initial = ((name, options[0]) for name, options in settings.CONFIG.items()) # Then update the mapping with actually values from the backend return dict(default_initial, **dict(config._backend.mget(settings.CONFIG))) + +def get_values_for_keys(keys): + """ + Retrieve values for specified keys from the backend. + + :param keys: List of keys to retrieve. + :return: Dictionary with values for the specified keys. + :raises AttributeError: If any key is not found in the configuration. + """ + if not isinstance(keys, (list, tuple, set)): + raise TypeError('keys must be a list, tuple, or set of strings') + + # Prepare default initial mapping + default_initial = { + name: options[0] for name, options in settings.CONFIG.items() if name in keys + } + + # Check if all keys are present in the default_initial mapping + missing_keys = [key for key in keys if key not in default_initial] + if missing_keys: + raise AttributeError(f'Key "{missing_keys[0]}" not found in configuration.') + + # Merge default values and backend values, prioritizing backend values + return dict(default_initial, **dict(config._backend.mget(keys))) diff --git a/tests/test_utils.py b/tests/test_utils.py index a9c1ba4..0804dda 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -5,7 +5,7 @@ from django.core.exceptions import ValidationError from django.test import TestCase from constance.management.commands.constance import _set_constance_value -from constance.utils import get_values +from constance.utils import get_values, get_values_for_keys class UtilsTestCase(TestCase): @@ -62,3 +62,24 @@ class UtilsTestCase(TestCase): }, }, ) + + def test_get_values_for_keys(self): + self.assertEqual( + get_values_for_keys(["BOOL_VALUE", "CHOICE_VALUE", "LINEBREAK_VALUE"]), + { + 'BOOL_VALUE': True, + 'CHOICE_VALUE': 'yes', + 'LINEBREAK_VALUE': 'Spam spam', + }, + ) + + def test_get_values_for_keys_empty_keys(self): + result = get_values_for_keys([]) + self.assertEqual(result, {}) + + def test_get_values_for_keys_throw_error_if_no_key(self): + self.assertRaisesMessage(AttributeError, 'Key "OLD_VALUE" not found in configuration.', get_values_for_keys, ['BOOL_VALUE', 'OLD_VALUE']) + + def test_get_values_for_keys_invalid_input_type(self): + with self.assertRaises(TypeError): + get_values_for_keys("key1") \ No newline at end of file