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.
python manage.py or
python manage.py help will show all registered commands grouped by app.
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:
| |-- management/
| | +-- commands/
| | +-- custom_command.py
| | +-- __init__.py
| |-- migrations/
| | +-- __init__.py
| |-- __init__.py
| |-- admin.py
| |-- apps.py
| |-- models.py
| |-- tests.py
| +-- views.py
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| |-- wsgi.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.
Let’s create a send_mail.py file.
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
To handle arguments in our custom command, we need to implement the
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)
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
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.
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!