diff --git a/django/views/debug.py b/django/views/debug.py
index 3d0a8c05f8..96d3e65189 100644
--- a/django/views/debug.py
+++ b/django/views/debug.py
@@ -46,6 +46,10 @@ def cleanse_setting(key, value):
     except TypeError:
         # If the key isn't regex-able, just return as-is.
         cleansed = value
+
+    if callable(cleansed):
+        cleansed.do_not_call_in_templates = True
+
     return cleansed
 
 def get_safe_settings():
diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py
index d885c22776..5c011a91b0 100644
--- a/tests/view_tests/tests/test_debug.py
+++ b/tests/view_tests/tests/test_debug.py
@@ -586,6 +586,16 @@ class ExceptionReporterFilterTests(TestCase, ExceptionReportTestMixin):
             self.verify_safe_response(sensitive_kwargs_function_caller, check_for_POST_params=False)
             self.verify_safe_email(sensitive_kwargs_function_caller, check_for_POST_params=False)
 
+    def test_callable_settings(self):
+        """
+        Callable settings should not be evaluated in the debug page (#21345).
+        """
+        def callable_setting():
+            return "This should not be displayed"
+        with self.settings(DEBUG=True, FOOBAR=callable_setting):
+            response = self.client.get('/views/raises500/')
+            self.assertNotContains(response, "This should not be displayed", status_code=500)
+
 
 class AjaxResponseExceptionReporterFilter(TestCase, ExceptionReportTestMixin):
     """