Skip to content

Commit 4a200d5

Browse files
Fix override_settings compat (#5668)
* Add test checking override_settings compat * Refresh APISettings, rather than replace Fix suggested by @daggaz #2466 (comment)
1 parent 1692feb commit 4a200d5

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

rest_framework/settings.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ def __init__(self, user_settings=None, defaults=None, import_strings=None):
200200
self._user_settings = self.__check_user_settings(user_settings)
201201
self.defaults = defaults or DEFAULTS
202202
self.import_strings = import_strings or IMPORT_STRINGS
203+
self._cached_attrs = set()
203204

204205
@property
205206
def user_settings(self):
@@ -223,6 +224,7 @@ def __getattr__(self, attr):
223224
val = perform_import(val, attr)
224225

225226
# Cache the result
227+
self._cached_attrs.add(attr)
226228
setattr(self, attr, val)
227229
return val
228230

@@ -233,15 +235,21 @@ def __check_user_settings(self, user_settings):
233235
raise RuntimeError("The '%s' setting has been removed. Please refer to '%s' for available settings." % (setting, SETTINGS_DOC))
234236
return user_settings
235237

238+
def reload(self):
239+
for attr in self._cached_attrs:
240+
delattr(self, attr)
241+
self._cached_attrs.clear()
242+
if hasattr(self, '_user_settings'):
243+
delattr(self, '_user_settings')
244+
236245

237246
api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)
238247

239248

240249
def reload_api_settings(*args, **kwargs):
241-
global api_settings
242-
setting, value = kwargs['setting'], kwargs['value']
250+
setting = kwargs['setting']
243251
if setting == 'REST_FRAMEWORK':
244-
api_settings = APISettings(value, DEFAULTS, IMPORT_STRINGS)
252+
api_settings.reload()
245253

246254

247255
setting_changed.connect(reload_api_settings)

tests/test_settings.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from __future__ import unicode_literals
22

3-
from django.test import TestCase
3+
from django.test import TestCase, override_settings
44

5-
from rest_framework.settings import APISettings
5+
from rest_framework.settings import APISettings, api_settings
66

77

88
class TestSettings(TestCase):
@@ -28,6 +28,23 @@ def test_warning_raised_on_removed_setting(self):
2828
'MAX_PAGINATE_BY': 100
2929
})
3030

31+
def test_compatibility_with_override_settings(self):
32+
"""
33+
Ref #5658 & #2466: Documented usage of api_settings
34+
is bound at import time:
35+
36+
from rest_framework.settings import api_settings
37+
38+
setting_changed signal hook must ensure bound instance
39+
is refreshed.
40+
"""
41+
assert api_settings.PAGE_SIZE is None, "Checking a known default should be None"
42+
43+
with override_settings(REST_FRAMEWORK={'PAGE_SIZE': 10}):
44+
assert api_settings.PAGE_SIZE == 10, "Setting should have been updated"
45+
46+
assert api_settings.PAGE_SIZE is None, "Setting should have been restored"
47+
3148

3249
class TestSettingTypes(TestCase):
3350
def test_settings_consistently_coerced_to_list(self):

0 commit comments

Comments
 (0)