Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions rest_framework/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ def __init__(self, user_settings=None, defaults=None, import_strings=None):
self._user_settings = self.__check_user_settings(user_settings)
self.defaults = defaults or DEFAULTS
self.import_strings = import_strings or IMPORT_STRINGS
self._cached_attrs = set()

@property
def user_settings(self):
Expand All @@ -223,6 +224,7 @@ def __getattr__(self, attr):
val = perform_import(val, attr)

# Cache the result
self._cached_attrs.add(attr)
setattr(self, attr, val)
return val

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

def reload(self):
for attr in self._cached_attrs:
delattr(self, attr)
self._cached_attrs.clear()
if hasattr(self, '_user_settings'):
delattr(self, '_user_settings')


api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)


def reload_api_settings(*args, **kwargs):
global api_settings
setting, value = kwargs['setting'], kwargs['value']
setting = kwargs['setting']
if setting == 'REST_FRAMEWORK':
api_settings = APISettings(value, DEFAULTS, IMPORT_STRINGS)
api_settings.reload()


setting_changed.connect(reload_api_settings)
21 changes: 19 additions & 2 deletions tests/test_settings.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from __future__ import unicode_literals

from django.test import TestCase
from django.test import TestCase, override_settings

from rest_framework.settings import APISettings
from rest_framework.settings import APISettings, api_settings


class TestSettings(TestCase):
Expand All @@ -28,6 +28,23 @@ def test_warning_raised_on_removed_setting(self):
'MAX_PAGINATE_BY': 100
})

def test_compatibility_with_override_settings(self):
"""
Ref #5658 & #2466: Documented usage of api_settings
is bound at import time:

from rest_framework.settings import api_settings

setting_changed signal hook must ensure bound instance
is refreshed.
"""
assert api_settings.PAGE_SIZE is None, "Checking a known default should be None"

with override_settings(REST_FRAMEWORK={'PAGE_SIZE': 10}):
assert api_settings.PAGE_SIZE == 10, "Setting should have been updated"

assert api_settings.PAGE_SIZE is None, "Setting should have been restored"


class TestSettingTypes(TestCase):
def test_settings_consistently_coerced_to_list(self):
Expand Down