diff --git a/django/contrib/auth/management/commands/changepassword.py b/django/contrib/auth/management/commands/changepassword.py index 669d8cf5d04..db980c82cab 100644 --- a/django/contrib/auth/management/commands/changepassword.py +++ b/django/contrib/auth/management/commands/changepassword.py @@ -4,7 +4,7 @@ from django.contrib.auth import get_user_model from django.contrib.auth.password_validation import validate_password from django.core.exceptions import ValidationError from django.core.management.base import BaseCommand, CommandError -from django.db import DEFAULT_DB_ALIAS +from django.db import DEFAULT_DB_ALIAS, connections UserModel = get_user_model() @@ -32,6 +32,7 @@ class Command(BaseCommand): parser.add_argument( "--database", default=DEFAULT_DB_ALIAS, + choices=tuple(connections), help='Specifies the database to use. Default is "default".', ) diff --git a/django/contrib/auth/management/commands/createsuperuser.py b/django/contrib/auth/management/commands/createsuperuser.py index 75ef68ff681..d5d5d193c84 100644 --- a/django/contrib/auth/management/commands/createsuperuser.py +++ b/django/contrib/auth/management/commands/createsuperuser.py @@ -11,7 +11,7 @@ from django.contrib.auth.management import get_default_username from django.contrib.auth.password_validation import validate_password from django.core import exceptions from django.core.management.base import BaseCommand, CommandError -from django.db import DEFAULT_DB_ALIAS +from django.db import DEFAULT_DB_ALIAS, connections from django.utils.functional import cached_property from django.utils.text import capfirst @@ -56,6 +56,7 @@ class Command(BaseCommand): parser.add_argument( "--database", default=DEFAULT_DB_ALIAS, + choices=tuple(connections), help='Specifies the database to use. Default is "default".', ) for field_name in self.UserModel.REQUIRED_FIELDS: diff --git a/django/contrib/contenttypes/management/commands/remove_stale_contenttypes.py b/django/contrib/contenttypes/management/commands/remove_stale_contenttypes.py index 950e615f0c8..27aaf1d51ba 100644 --- a/django/contrib/contenttypes/management/commands/remove_stale_contenttypes.py +++ b/django/contrib/contenttypes/management/commands/remove_stale_contenttypes.py @@ -3,7 +3,7 @@ import itertools from django.apps import apps from django.contrib.contenttypes.models import ContentType from django.core.management import BaseCommand -from django.db import DEFAULT_DB_ALIAS, router +from django.db import DEFAULT_DB_ALIAS, connections, router from django.db.models.deletion import Collector @@ -21,6 +21,7 @@ class Command(BaseCommand): parser.add_argument( "--database", default=DEFAULT_DB_ALIAS, + choices=tuple(connections), help='Nominates the database to use. Defaults to the "default" database.', ) parser.add_argument( diff --git a/django/core/management/commands/check.py b/django/core/management/commands/check.py index 6348c9fc681..e61cff79f3f 100644 --- a/django/core/management/commands/check.py +++ b/django/core/management/commands/check.py @@ -2,6 +2,7 @@ from django.apps import apps from django.core import checks from django.core.checks.registry import registry from django.core.management.base import BaseCommand, CommandError +from django.db import connections class Command(BaseCommand): @@ -43,6 +44,7 @@ class Command(BaseCommand): parser.add_argument( "--database", action="append", + choices=tuple(connections), dest="databases", help="Run database related checks against these aliases.", ) diff --git a/django/core/management/commands/createcachetable.py b/django/core/management/commands/createcachetable.py index 65ed1686d20..a8965b1edcd 100644 --- a/django/core/management/commands/createcachetable.py +++ b/django/core/management/commands/createcachetable.py @@ -30,6 +30,7 @@ class Command(BaseCommand): parser.add_argument( "--database", default=DEFAULT_DB_ALIAS, + choices=tuple(connections), help="Nominates a database onto which the cache tables will be " 'installed. Defaults to the "default" database.', ) diff --git a/django/core/management/commands/dbshell.py b/django/core/management/commands/dbshell.py index bdb130594fa..b177a7e0835 100644 --- a/django/core/management/commands/dbshell.py +++ b/django/core/management/commands/dbshell.py @@ -16,6 +16,7 @@ class Command(BaseCommand): parser.add_argument( "--database", default=DEFAULT_DB_ALIAS, + choices=tuple(connections), help=( "Nominates a database onto which to open a shell. Defaults to the " '"default" database.' diff --git a/django/core/management/commands/dumpdata.py b/django/core/management/commands/dumpdata.py index 01ff8974dd1..5a9ab839196 100644 --- a/django/core/management/commands/dumpdata.py +++ b/django/core/management/commands/dumpdata.py @@ -6,7 +6,7 @@ from django.apps import apps from django.core import serializers from django.core.management.base import BaseCommand, CommandError from django.core.management.utils import parse_apps_and_model_labels -from django.db import DEFAULT_DB_ALIAS, router +from django.db import DEFAULT_DB_ALIAS, connections, router try: import bz2 @@ -56,6 +56,7 @@ class Command(BaseCommand): parser.add_argument( "--database", default=DEFAULT_DB_ALIAS, + choices=tuple(connections), help="Nominates a specific database to dump fixtures from. " 'Defaults to the "default" database.', ) diff --git a/django/core/management/commands/flush.py b/django/core/management/commands/flush.py index e9d440dd865..a057393d53e 100644 --- a/django/core/management/commands/flush.py +++ b/django/core/management/commands/flush.py @@ -25,6 +25,7 @@ class Command(BaseCommand): parser.add_argument( "--database", default=DEFAULT_DB_ALIAS, + choices=tuple(connections), help='Nominates a database to flush. Defaults to the "default" database.', ) diff --git a/django/core/management/commands/inspectdb.py b/django/core/management/commands/inspectdb.py index 5c2ed53db8f..77605b178f6 100644 --- a/django/core/management/commands/inspectdb.py +++ b/django/core/management/commands/inspectdb.py @@ -25,6 +25,7 @@ class Command(BaseCommand): parser.add_argument( "--database", default=DEFAULT_DB_ALIAS, + choices=tuple(connections), help=( 'Nominates a database to introspect. Defaults to using the "default" ' "database." diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py index bb46e8ae78c..8c76e526338 100644 --- a/django/core/management/commands/loaddata.py +++ b/django/core/management/commands/loaddata.py @@ -55,6 +55,7 @@ class Command(BaseCommand): parser.add_argument( "--database", default=DEFAULT_DB_ALIAS, + choices=tuple(connections), help=( "Nominates a specific database to load fixtures into. Defaults to the " '"default" database.' diff --git a/django/core/management/commands/migrate.py b/django/core/management/commands/migrate.py index 3a0e9e87ff8..5e6b19c0953 100644 --- a/django/core/management/commands/migrate.py +++ b/django/core/management/commands/migrate.py @@ -47,6 +47,7 @@ class Command(BaseCommand): parser.add_argument( "--database", default=DEFAULT_DB_ALIAS, + choices=tuple(connections), help=( 'Nominates a database to synchronize. Defaults to the "default" ' "database." diff --git a/django/core/management/commands/showmigrations.py b/django/core/management/commands/showmigrations.py index 203f92151d2..e88f83f273a 100644 --- a/django/core/management/commands/showmigrations.py +++ b/django/core/management/commands/showmigrations.py @@ -19,6 +19,7 @@ class Command(BaseCommand): parser.add_argument( "--database", default=DEFAULT_DB_ALIAS, + choices=tuple(connections), help=( "Nominates a database to show migrations for. Defaults to the " '"default" database.' diff --git a/django/core/management/commands/sqlflush.py b/django/core/management/commands/sqlflush.py index bc82e1f05ff..d0512a68a83 100644 --- a/django/core/management/commands/sqlflush.py +++ b/django/core/management/commands/sqlflush.py @@ -16,6 +16,7 @@ class Command(BaseCommand): parser.add_argument( "--database", default=DEFAULT_DB_ALIAS, + choices=tuple(connections), help=( 'Nominates a database to print the SQL for. Defaults to the "default" ' "database." diff --git a/django/core/management/commands/sqlmigrate.py b/django/core/management/commands/sqlmigrate.py index 2f6993682f6..3e3151f0cf3 100644 --- a/django/core/management/commands/sqlmigrate.py +++ b/django/core/management/commands/sqlmigrate.py @@ -19,6 +19,7 @@ class Command(BaseCommand): parser.add_argument( "--database", default=DEFAULT_DB_ALIAS, + choices=tuple(connections), help=( 'Nominates a database to create SQL for. Defaults to the "default" ' "database." diff --git a/django/core/management/commands/sqlsequencereset.py b/django/core/management/commands/sqlsequencereset.py index 9653fa59d00..cc0d100499b 100644 --- a/django/core/management/commands/sqlsequencereset.py +++ b/django/core/management/commands/sqlsequencereset.py @@ -14,6 +14,7 @@ class Command(AppCommand): parser.add_argument( "--database", default=DEFAULT_DB_ALIAS, + choices=tuple(connections), help=( 'Nominates a database to print the SQL for. Defaults to the "default" ' "database." diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py index 688aaa0a2f8..c2bb9f9e5d2 100644 --- a/tests/admin_scripts/tests.py +++ b/tests/admin_scripts/tests.py @@ -2301,6 +2301,35 @@ class Discovery(SimpleTestCase): self.assertEqual(out.getvalue().strip(), "simple_app") +class CommandDBOptionChoiceTests(SimpleTestCase): + def test_invalid_choice_db_option(self): + expected_error = ( + "Error: argument --database: invalid choice: " + "'deflaut' (choose from 'default', 'other')" + ) + args = [ + "changepassword", + "createsuperuser", + "remove_stale_contenttypes", + "check", + "createcachetable", + "dbshell", + "flush", + "dumpdata", + "inspectdb", + "loaddata", + "showmigrations", + "sqlflush", + "sqlmigrate", + "sqlsequencereset", + "migrate", + ] + + for arg in args: + with self.assertRaisesMessage(CommandError, expected_error): + call_command(arg, "--database", "deflaut", verbosity=0) + + class ArgumentOrder(AdminScriptTestCase): """Tests for 2-stage argument parsing scheme.