How To Create Custom Management Commands in Django
When developing applications using the Django framework, we extensively use various Django commands like
python manage.py runserver
python manage.py makemigrations
python manage.py migrate
These commands are built-in and lie within Django itself.
Invoking python manage.py
or python manage.py help
will show all registered commands grouped by app.
Output :
Available subcommands:[auth]
changepassword
createsuperuser[contenttypes]
remove_stale_contenttypes[default]
create_user
run_seeder[django]
check
compilemessages
createcachetable
dbshell
diffsettings
dumpdata
flush
inspectdb
loaddata
makemessages
makemigrations
migrate
sendtestemail
shell
showmigrations
sqlflush
sqlmigrate
sqlsequencereset
squashmigrations
startapp
startproject
test
testserver[django_mysql]
cull_mysql_caches
dbparams
fix_datetime_columns
mysql_cache_migration[oauth2_provider]
cleartokens[sessions]
clearsessions[staticfiles]
collectstatic
findstatic
runserver
We can also write and register our own management commands and include them in the list. For that, we have to create management/commands directory inside an app directory, like below:
mysite/
|-- core/
| |-- management/
| | +-- commands/
| | +-- custom_command.py
| | +-- __init__.py
| |-- migrations/
| | +-- __init__.py
| |-- __init__.py
| |-- admin.py
| |-- apps.py
| |-- models.py
| |-- tests.py
| +-- views.py
|-- mysite/
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| |-- wsgi.py
+-- manage.py
Here, The name of the file is custom_command.py. So custom_command is added to Django’s command list. We will be able to execute it via
python manage.py custom_command
Let’s explore how to implement custom commands in detail with examples.
Basic Example
Let’s create a send_mail.py file.
The handle
method contains the core command logic and is automatically run when invoking the command. The handle
method declares three input argument: self
to reference the class instance; *args
to reference arguments of the method itself; and **kwargs
to reference arguments passed as part of the management command.
This custom command can be called using
python manage.py send_mail
Accepting arguments
To handle arguments in our custom command, we need to implement the add_arguments()
method.
Let’s consider we have a total three types of roles in our application: superadmin, admin, and staff. We want to create users using the create_users command by sending two arguments :
- role_type: Indicate name of roles like staff, admin, or superadmin(mandatory argument)
- number_of_users: Indicates how many users we want to create(Optional argument which has 1 as default value)
The add_arguments()
method must define a task's arguments, including their type, default value, and help message, among other things. In essence, the add_arguments()
method works as a pre-processor to command arguments, which are then made available in the **kwargs
argument of the handle()
method.
In our example, we declare both a positional and an optional argument. Both arguments are added to the parser.add_argument()
method. The difference being, optional arguments use leading dashes -- and if omitted, then an argument is assumed to be positional.
Positional arguments by definition are required. So in this case, the role_type
argument is expected otherwise Django throws 'too few arguments' errors.
Optional arguments are not compulsory. Here, number_of_users
is not mandatory and it declares 1 as a default value.
Example usage:
python manage.py create_users superadmin
This command will create one superadmin in our application.
If we want to create n number of users, we can do that via
python manage.py create_users staff 10
This will create 10 users who have staff as role_type
Running management commands from code
In some situations, we have to run management commands from code instead of the terminal. The call_command()
allows us to invoke a management command from code.
Scheduled Management commands
There are many use cases like
- We have a web scraper that collects data from some Website every 30 minutes and store data in a database
- We want to send user’s report mail to our marketing team daily
- The development team gets error logs data of the production server every Monday
where we want to run custom management commands at scheduled intervals of time such as daily, every Monday, monthly, etc. This can be done by periodically executing the management command from the UNIX crontab or from Windows scheduled tasks control panel.
The example above will execute the send_mail
every midnight.
If you have any questions or suggestions, please feel free to leave them in the responses below! Thanks for your time!