Chapter 21 · Management commands
21.7 The commands Django ships
The management commands that come with Django, by what each one drives: those of django/ and those of the contrib applications, the few whose classes reach into the machinery instead of only filling in handle, and the base class behind startproject and startapp, TemplateCommand.
Most of Django’s commands are thin fronts. Such a command’s handle reads the options, picks a database connection or a few applications, and hands the work to a subsystem that would do the same if it were called from anywhere else. To know what migrate really does is to know the migration executor, and the command’s module is the wrong place to look for that. A few carry their work themselves: inspectdb writes model source from what a database reports, makemessages drives a set of external programs, the shell builds a namespace. So this page is mostly a map from each command to the code that does its work, and from there to the chapter that explains it.
Django’s own commands
These are the modules of django/, which are commands in every project and the only commands where there are no settings.
django/core/management/commands/ , by what does their work.| command | its handle hands the work to |
told in |
|---|---|---|
| makemigrations | its handle hands the work to the autodetector, which compares the models with the state the migration files describe, and the writer, which turns the difference into files Migration django/ |
told in The makemigrations command |
| migrate | its handle hands the work to the executor, which applies or unapplies migrations to reach a target; the command sends the pre_migrate and post_migrate signals around it Migration django/ |
told in The migrate command, showmigrations and sqlmigrate |
| showmigrations | its handle hands the work to the loader’s graph and the recorder’s table, to list migrations or the plan Command django/ |
told in The migrate command, showmigrations and sqlmigrate |
| sqlmigrate | its handle hands the work to the loader, which runs one migration against a schema editor that collects SQL and executes nothing Migration django/ |
told in The migrate command, showmigrations and sqlmigrate |
| squashmigrations, optimizemigration | its handle hands the work to the optimizer, which shortens a list of operations, and the writer Migration django/ |
told in Squashed migrations: replaces and the squashmigrations command, The optimizer: Migration and reduce |
| dbshell | its handle hands the work to the backend’s client class, which runs the database’s own command-line program Base django/ |
told in The connection object: Base and what a backend provides |
| inspectdb | its handle hands the work to the backend’s introspection, from whose answers the command prints model source Base django/ |
told in Introspection: reading the schema back |
| sqlflush | its handle hands the work to a function that picks every existing table of the installed, managed models and has the backend’s operations build the statements that would empty them sql_flush django/ |
told in Introspection: reading the schema back |
| flush | its handle hands the work to the same statements, executed, and then the post_migrate signal Base django/ |
told in Introspection: reading the schema back |
| sqlsequencereset | its handle hands the work to the backend’s operations, for the statements that reset the sequences of some applications’ tables Base django/ |
told in Introspection: reading the schema back |
| dumpdata | its handle hands the work to a serializer, fed the rows of the chosen models serialize django/ |
told in Fixtures: dumpdata and loaddata |
| loaddata | its handle hands the work to a deserializer, inside one transaction with constraint checking put off to its end Command.loaddata django/ |
told in Fixtures: dumpdata and loaddata |
| createcachetable | its handle hands the work to nothing else: the command builds the statements for the database cache’s table itself Command django/ |
told in The cache backends |
| sendtestemail | its handle hands the work to the mail functions send_mail django/ |
told in Sending email: mailers and the email backends |
| makemessages, compilemessages | its handle hands the work to the GNU gettext programs, run as child processes popen_wrapper django/ |
told in Making catalogues: makemessages and compilemessages |
| test | its handle hands the work to the test runner class, named by --testrunner or else by settings, and its method that runs the tests Discover django/ |
told in The runner: the test command and DiscoverRunner |
| listurls | its handle hands the work to a walk over the root URLconf’s patterns extract_ django/ |
told in URL routing |
| diffsettings | its handle hands the work to a comparison of the loaded settings with global_ django/conf/ Command.handle django/ |
told in Settings, apps and startup |
| check | its handle hands the work to the check framework Base django/ |
told in The system checks |
| runserver | its handle hands the work to the development server run django/ |
told in The development server |
| testserver | its handle hands the work to the code that makes a test database, and then the loaddata and runserver commands, called from code Command.handle django/ |
told in The development server |
| startproject, startapp | its handle hands the work to TemplateCommand |
told in below |
| shell | its handle hands the work to an interactive interpreter |
told in below |
Some functions that several of these share live beside the commands. emit_pre_migrate_signal and emit_post_migrate_signal send the two signals once for each installed application that has a models module; migrate calls both, and flush the second. And run_formatters runs the Black formatter, if one is installed, over the files or the directory a command has just written; the migration commands that write files and the two template commands call it.
The commands of the contrib applications
A contrib application’s commands exist in a project that installs the application, and are found like any other application’s (Finding the command).
| application | command | what it does |
|---|---|---|
django |
command createsuperuser | what it does asks for, or reads from the environment, the fields of the user model, and calls the model manager’s method that makes a superuser Command.handle django/ |
| command changepassword | what it does asks for a password twice, validates it and saves it on the user Command.handle django/ |
|
django |
command remove_stale_contenttypes | what it does deletes the content types of installed applications whose model no longer exists, after listing, when it can ask for confirmation, what would go with them Command.handle django/ |
django |
command clearsessions | what it does calls the session engine’s method that removes expired sessions Session django/ |
django |
command collectstatic | what it does copies or links into the static files storage the first file found for each path among those the finders list, then lets the storage process them Command.collect django/ |
| command findstatic | what it does asks the finders where a file is find django/ |
|
| command runserver | what it does Django’s runserver, with static files served (The development server) | |
django |
command inspectdb | what it does Django’s inspectdb, taught the geometry column types Command django/ |
| command ogrinspect | what it does prints model source for a layer of a geographic data file _ogrinspect django/ |
Two of them have the name of a command of Django’s and take its place, each by subclassing the class it displaces.
The name management has a second use. The auth, contenttypes and sites applications each keep, in a module of that name, the functions that run when migrate has finished its work, to create permissions, content types and the default site among other things, and connect them to post_migrate in their AppConfig.ready. For an application that connects such receivers in the module itself, migrate and flush import the management module of every installed application at the start of their handle.
The few that reach into the machinery
A command usually leaves BaseCommand alone and defines add_arguments and handle. This is what each class of the recorded project’s Django does beyond that: which of the attributes that steer the machinery its own class sets, and which methods of the machinery it overrides. The class’s help text and its message for missing arguments, which many set, are not counted. Classes of django.core that do neither are left out, with a line of dots where they were.
The commands of django.core and of django.contrib.staticfiles: the base of each, and what its own class sets and overrides of what BaseCommand defines
django.core
check (BaseCommand)
requires_system_checks = []
compilemessages (BaseCommand)
requires_system_checks = []
createcachetable (BaseCommand)
requires_system_checks = []
dbshell (BaseCommand)
requires_system_checks = []
diffsettings (BaseCommand)
requires_system_checks = []
...
flush (BaseCommand)
stealth_options = ["reset_sequences", "allow_cascade", "inhibit_post_migrate"]
inspectdb (BaseCommand)
requires_system_checks = []
stealth_options = ["table_name_filter"]
listurls (BaseCommand)
overrides __init__
...
makemessages (BaseCommand)
requires_system_checks = []
requires_settings = False
...
migrate (BaseCommand)
overrides get_check_kwargs
...
runserver (BaseCommand)
stealth_options = ["shutdown_message"]
suppressed_base_arguments = ["--traceback", "--verbosity"]
overrides execute, get_check_kwargs
...
shell (BaseCommand)
requires_system_checks = []
requires_settings = False
...
sqlflush (BaseCommand)
output_transaction = True
sqlmigrate (BaseCommand)
output_transaction = True
overrides execute
sqlsequencereset (AppCommand)
output_transaction = True
...
startapp (templates.TemplateCommand)
requires_settings = False
startproject (templates.TemplateCommand)
requires_settings = False
test (BaseCommand)
requires_system_checks = []
overrides run_from_argv
testserver (BaseCommand)
requires_system_checks = []
django.contrib.staticfiles
collectstatic (BaseCommand)
requires_system_checks = ["staticfiles"]
overrides __init__
findstatic (LabelCommand)
runserver (runserver.Command)
About half ask for no system checks, counting the two template commands, which inherit an empty list from TemplateCommand. Two of those run the checks themselves, at a time of their choosing: check, whose whole purpose it is, and test, whose runner calls check once the test databases exist; a comment in the test command says so. The rest are the two that make a project or an application, shell and dbshell, the two for translation files, and inspectdb, diffsettings, createcachetable and testserver.
Four can run without settings, the two that create a project or an application, the shell, and makemessages (Finding the command).
A handful override a method of the machinery, and each for a reason of its own.
- test overrides
BaseCommand. The test runner class may add arguments to the command’s parser, and which class is the runner can itself be an option,.run_from_argv --testrunner. So the option has to be read from the raw arguments before the parser is built. - runserver overrides
executeandget_check_kwargs, to carry--no-colorto the server’s log and to move the checks to the process that serves (The development server). - migrate overrides
get_check_kwargs, to have the checks run against the database it will migrate. - sqlmigrate overrides
executeto take the colour out of the transaction statements that are put around its output, since the rest of what it prints is not coloured. It also decides inhandle, for each run, whether those statements are wanted at all: only for a migration that is atomic on a database that can roll back changes to its schema. - listurls and collectstatic override
__init__: the first to choose its own style object, the second to set up its lists of files, its storage and a style without colour.
One more is not in the recording because its application is not installed there. The createsuperuser command overrides __init__, to find the user model before its arguments are declared, and execute, to accept in place of standard input a stream that it asks only whether it is a terminal, declared as a stealth option and, its comment says, used for testing; its prompts still read standard input (Creating a superuser: createsuperuser and changepassword).
Commands that write a project: TemplateCommand
startproject and startapp are one class with two names. Each is a TemplateCommand whose handle passes on the word “project” or “app”, and the project one adds a freshly generated secret key.
TemplateCommand copies a directory, and renders some of the files on the way.
- It checks the name: a valid Python identifier, and not the name of a module that can already be imported, with which the new one would conflict.
- It makes or accepts the target directory.
- It prepares the template engine. With no settings configured it configures the defaults and calls
django.setup, so that the engine can run in an empty directory (Who callsdjango.setup). - It finds the template directory. By default that is
django/orconf/ project_template/ django/. Withconf/ app_template/ --templateit is a directory, or an archive that is unpacked into a temporary place, or a URL that is downloaded first. - It walks the template directory, creating each directory and file under the target, with the placeholder in a file’s or a directory’s name replaced by the real name. Compiled Python files are passed over, and so are hidden directories, or with
--excludethe directories that option names. A file whose extension is one of those to render,.pyand any that--extensionadds, or whose name--namelists, is passed through the Django template language with the name, the directory, Django’s version and a few more values as its context; every other file is copied as it is. A file that already exists at the destination stops the command. - It runs a formatter over the target directory, if one is installed. It looked for the formatter before step 4, so that nothing a template brought with it could be found in its place.
Two details of step 5 explain the look of the template directories. Their Python files are named with -tpl after the extension, and the command removes it when it writes them: a comment gives the reason, that a file full of template tags is not valid Python and must not be compiled when Django is installed. And the rendering is done with autoescaping off.
The shell
The shell command starts an interactive interpreter in a process where Django has been started. It tries IPython, then bpython, then Python’s own code module, and uses the first that can be imported, or the one --interface names. With --command it executes a string and exits, and where the platform allows it does the same with whatever is piped to its standard input.
What it adds to a bare interpreter is a namespace. Command in that file returns a list of dotted paths, and each is imported and bound under its last part: the settings object, the default database connection, the ORM’s modules of models and of database functions, the function that empties the log of queries, the timezone module, and then every model class the app registry lists, which leaves out the models made automatically for many-to-many relations and the models that have been swapped for others. Where two models have the same name, the one from the application listed earlier in settings is the one bound. A project changes the list by subclassing the command and overriding that method, in an application of its own.
The command declares that it can run without settings. When there are none, it says that automatic imports are off, and why, and starts the interpreter with an empty namespace.