Refs #27829 -- Added warning for settings.DEFAULT_CONTENT_TYPE usage outside of Django.

This commit is contained in:
Jon Dufresne 2018-10-15 11:46:35 -07:00 committed by Tim Graham
parent 1299421cad
commit 99d4fc18bd
2 changed files with 36 additions and 4 deletions

View File

@ -9,9 +9,11 @@ for a list of all possible variables.
import importlib import importlib
import os import os
import time import time
import traceback
import warnings import warnings
from pathlib import Path from pathlib import Path
import django
from django.conf import global_settings from django.conf import global_settings
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.utils.deprecation import RemovedInDjango30Warning from django.utils.deprecation import RemovedInDjango30Warning
@ -19,6 +21,8 @@ from django.utils.functional import LazyObject, empty
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE" ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
DEFAULT_CONTENT_TYPE_DEPRECATED_MSG = 'The DEFAULT_CONTENT_TYPE setting is deprecated.'
class LazySettings(LazyObject): class LazySettings(LazyObject):
""" """
@ -93,6 +97,20 @@ class LazySettings(LazyObject):
"""Return True if the settings have already been configured.""" """Return True if the settings have already been configured."""
return self._wrapped is not empty return self._wrapped is not empty
@property
def DEFAULT_CONTENT_TYPE(self):
stack = traceback.extract_stack()
# Show a warning if the setting is used outside of Django.
# Stack index: -1 this line, -2 the caller.
filename, _line_number, _function_name, _text = stack[-2]
if not filename.startswith(os.path.dirname(django.__file__)):
warnings.warn(
DEFAULT_CONTENT_TYPE_DEPRECATED_MSG,
RemovedInDjango30Warning,
stacklevel=2,
)
return self.__getattr__('DEFAULT_CONTENT_TYPE')
class Settings: class Settings:
def __init__(self, settings_module): def __init__(self, settings_module):
@ -126,7 +144,7 @@ class Settings:
raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.") raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.")
if self.is_overridden('DEFAULT_CONTENT_TYPE'): if self.is_overridden('DEFAULT_CONTENT_TYPE'):
warnings.warn('The DEFAULT_CONTENT_TYPE setting is deprecated.', RemovedInDjango30Warning) warnings.warn(DEFAULT_CONTENT_TYPE_DEPRECATED_MSG, RemovedInDjango30Warning)
if hasattr(time, 'tzset') and self.TIME_ZONE: if hasattr(time, 'tzset') and self.TIME_ZONE:
# When we can, attempt to validate the timezone. If we can't find # When we can, attempt to validate the timezone. If we can't find
@ -172,7 +190,7 @@ class UserSettingsHolder:
def __setattr__(self, name, value): def __setattr__(self, name, value):
self._deleted.discard(name) self._deleted.discard(name)
if name == 'DEFAULT_CONTENT_TYPE': if name == 'DEFAULT_CONTENT_TYPE':
warnings.warn('The DEFAULT_CONTENT_TYPE setting is deprecated.', RemovedInDjango30Warning) warnings.warn(DEFAULT_CONTENT_TYPE_DEPRECATED_MSG, RemovedInDjango30Warning)
super().__setattr__(name, value) super().__setattr__(name, value)
def __delattr__(self, name): def __delattr__(self, name):

View File

@ -1,13 +1,13 @@
import sys import sys
from types import ModuleType from types import ModuleType
from django.conf import Settings from django.conf import DEFAULT_CONTENT_TYPE_DEPRECATED_MSG, Settings, settings
from django.test import SimpleTestCase, ignore_warnings from django.test import SimpleTestCase, ignore_warnings
from django.utils.deprecation import RemovedInDjango30Warning from django.utils.deprecation import RemovedInDjango30Warning
class DefaultContentTypeTests(SimpleTestCase): class DefaultContentTypeTests(SimpleTestCase):
msg = 'The DEFAULT_CONTENT_TYPE setting is deprecated.' msg = DEFAULT_CONTENT_TYPE_DEPRECATED_MSG
@ignore_warnings(category=RemovedInDjango30Warning) @ignore_warnings(category=RemovedInDjango30Warning)
def test_default_content_type_is_text_html(self): def test_default_content_type_is_text_html(self):
@ -42,3 +42,17 @@ class DefaultContentTypeTests(SimpleTestCase):
Settings('fake_settings_module') Settings('fake_settings_module')
finally: finally:
del sys.modules['fake_settings_module'] del sys.modules['fake_settings_module']
def test_access_warning(self):
with self.assertRaisesMessage(RemovedInDjango30Warning, self.msg):
settings.DEFAULT_CONTENT_TYPE
# Works a second time.
with self.assertRaisesMessage(RemovedInDjango30Warning, self.msg):
settings.DEFAULT_CONTENT_TYPE
@ignore_warnings(category=RemovedInDjango30Warning)
def test_access(self):
with self.settings(DEFAULT_CONTENT_TYPE='text/xml'):
self.assertEqual(settings.DEFAULT_CONTENT_TYPE, 'text/xml')
# Works a second time.
self.assertEqual(settings.DEFAULT_CONTENT_TYPE, 'text/xml')