summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Forbes <tom@tomforb.es>2018-02-21 14:00:49 +0000
committerTim Graham <timograham@gmail.com>2018-02-21 09:00:49 -0500
commit33ac036a6bcab64ef93d0185f7b55eb57e559d6e (patch)
treea65c4d1618d3acb7ffbd4c2d312503305d6f4078
parentf7b46f0b589fce13b5cb628cabb56900e2050dfe (diff)
Fixed #28398 -- Added suggestions for mistyped management commands.
-rw-r--r--django/core/management/__init__.py10
-rw-r--r--tests/admin_scripts/tests.py20
2 files changed, 26 insertions, 4 deletions
diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py
index 9a565a9393..4d26c98d09 100644
--- a/django/core/management/__init__.py
+++ b/django/core/management/__init__.py
@@ -3,6 +3,7 @@ import os
import pkgutil
import sys
from collections import OrderedDict, defaultdict
+from difflib import get_close_matches
from importlib import import_module
import django
@@ -203,10 +204,11 @@ class ManagementUtility:
settings.INSTALLED_APPS
else:
sys.stderr.write("No Django settings specified.\n")
- sys.stderr.write(
- "Unknown command: %r\nType '%s help' for usage.\n"
- % (subcommand, self.prog_name)
- )
+ possible_matches = get_close_matches(subcommand, commands)
+ sys.stderr.write('Unknown command: %r' % subcommand)
+ if possible_matches:
+ sys.stderr.write('. Did you mean %s?' % possible_matches[0])
+ sys.stderr.write("\nType '%s help' for usage.\n" % self.prog_name)
sys.exit(1)
if isinstance(app_name, BaseCommand):
# If the command is already loaded, use it directly.
diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py
index e9f5a1897b..d34f95ea40 100644
--- a/tests/admin_scripts/tests.py
+++ b/tests/admin_scripts/tests.py
@@ -2256,3 +2256,23 @@ class MainModule(AdminScriptTestCase):
def test_program_name_in_help(self):
out, err = self.run_test('-m', ['django', 'help'])
self.assertOutput(out, "Type 'python -m django help <subcommand>' for help on a specific subcommand.")
+
+
+class DjangoAdminSuggestions(AdminScriptTestCase):
+ def setUp(self):
+ self.write_settings('settings.py')
+
+ def tearDown(self):
+ self.remove_settings('settings.py')
+
+ def test_suggestions(self):
+ args = ['rnserver', '--settings=test_project.settings']
+ out, err = self.run_django_admin(args)
+ self.assertNoOutput(out)
+ self.assertOutput(err, "Unknown command: 'rnserver'. Did you mean runserver?")
+
+ def test_no_suggestions(self):
+ args = ['abcdef', '--settings=test_project.settings']
+ out, err = self.run_django_admin(args)
+ self.assertNoOutput(out)
+ self.assertNotInOutput(err, 'Did you mean')