How to Create Custom Command in Django?

Published On: 12/09/2022 | Category: Django


Hi Dev,

If you need to see example of how to create custom django commands. In this article, we will implement a how to create custom django management commands. you can see custom django management commands example. In this article, we will implement a how to create custom command in django.

In your Django project manage.py file in Django is a command-line utility that works similar to the django-admin command. The difference is that it points towards the project’s settings.py file. This manage.py utility provides various commands that you must have while working with django.

Here i explained simply step by step example of how to create custom django commands in django.

Step 1: Create a Project

In this step, we’ll create a new django project using the django-admin. Head back to your command-line interface and run the following command:

django-admin startproject example
Step 2: Create a App

Now we'll create a single app called core to store a list of post names. We're keeping things intentionally basic. Stop the local server with Control+c and use the startapp command to create this new app.

python3 manage.py startapp core
Step 3: Update setting.py

Next, then update INSTALLED_APPS within our settings.py file to notify Django about the app.

Next, you need to add it in the settings.py file as follows:

settings.py

....
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'core',
]

Now, we can create our own commands for our apps and include them in the list by creating a management/commands directory inside an core app directory, like below:

example/                                   <-- project directory
 |-- core/                                <-- app directory
 |    |-- management/
 |    |    +-- commands/
 |    |         +-- my_command.py  <-- your command...
 |    |-- migrations/
 |    |    +-- __init__.py
 |    |-- __init__.py
 |    |-- admin.py
 |    |-- apps.py
 |    |-- models.py
 |    |-- tests.py
 |    +-- views.py
 |-- example/
 |    |-- __init__.py
 |    |-- settings.py
 |    |-- urls.py
 |    |-- wsgi.py
 +-- manage.py

The name of the command file will be used to invoke using the command line utility. For example, if our command was called my_command.py, then we will be able to call it via below following through command:

python manage.py my_command

Now, so start the our basic django custom command like this..

So, Django management command is composed by a class named Command which inherits from BaseCommand. The command code should be defined inside the handle() method look like the below following code.

management/commands/current_time.py
from django.core.management.base import BaseCommand
from django.utils import timezone

class Command(BaseCommand):
    help = 'Displays current time'

    def handle(self, *args, **kwargs):
        time = timezone.now().strftime('%X')
        self.stdout.write("It's Time now %s" % time)

See how we named our module current_time.py. This command can be executed as:

Output
It's Time now 10:30:49
Handling Arguments in Django Commands

so, In this section we need to discuss about arguments in django command so django custom management command comes to so many argument like Positional Arguments, Optional Arguments, Flag Arguments, Arbitrary List of Arguments in django.

Positional Arguments

First of all we need to talk about Positional Arguments in django this example is a command that create random user instances. It takes a mandatory argument named total, which will define the number of users that will be created by the command.

management/commands/create_users.py
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand
from django.utils.crypto import get_random_string

class Command(BaseCommand):
    help = 'Create random users'

    def add_arguments(self, parser):
        parser.add_argument('total', type=int, help='Indicates the number of users to be created')

    def handle(self, *args, **kwargs):
        total = kwargs['total']
        for i in range(total):
            User.objects.create_user(username=get_random_string(), email='', password='123456')

See how we named our module create_users.py. This command can be executed as:

Output
python manage.py create_users 10
Optional Arguments

Second argument of all we need to talk about Optional Arguments In the example below you will find the definition of an argument named “prefix”, which will be used to compose the username field:

management/commands/create_users.py
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand
from django.utils.crypto import get_random_string

class Command(BaseCommand):
    help = 'Create random users'

    def add_arguments(self, parser):
        parser.add_argument('total', type=int, help='Indicates the number of users to be created')

        # Optional argument
        parser.add_argument('-p', '--prefix', type=str, help='Define a username prefix', )

    def handle(self, *args, **kwargs):
        total = kwargs['total']
        prefix = kwargs['prefix']

        for i in range(total):
            if prefix:
                username = '{prefix}_{random_string}'.format(prefix=prefix, random_string=get_random_string())
            else:
                username = get_random_string()
            User.objects.create_user(username=username, email='', password='123')

See how we named our module create_users.py. This command can be executed as:

Output
python manage.py create_users 10 --prefix custom_user 10

or

python manage.py create_users 10 -p custom_user
Output

Flag Arguments

Third argument of all we need to talk about Flag Arguments which are used to handle boolean values we want to add an --admin flag, to instruct our command to create a super user or to create a regular user if the flag is not present.

management/commands/create_users.py
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand
from django.utils.crypto import get_random_string

class Command(BaseCommand):
    help = 'Create random users'

    def add_arguments(self, parser):
        parser.add_argument('total', type=int, help='Indicates the number of users to be created')
        parser.add_argument('-p', '--prefix', type=str, help='Define a username prefix')
        parser.add_argument('-a', '--admin', action='store_true', help='Create an admin account')

    def handle(self, *args, **kwargs):
        total = kwargs['total']
        prefix = kwargs['prefix']
        admin = kwargs['admin']

        for i in range(total):
            if prefix:
                username = '{prefix}_{random_string}'.format(prefix=prefix, random_string=get_random_string())
            else:
                username = get_random_string()

            if admin:
                User.objects.create_superuser(username=username, email='', password='123')
            else:
                User.objects.create_user(username=username, email='', password='123')

See how we named our module create_users.py. This command can be executed as:

Output
python manage.py create_users 2 --admin

or

python manage.py create_users 2 -a

create a new command now named delete_users. In this new command we will be able to pass a list of user ids and the command should delete those users from the database.

management/commands/delete_users.py
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand

class Command(BaseCommand):
    help = 'Delete users'

    def add_arguments(self, parser):
        parser.add_argument('user_id', nargs='+', type=int, help='User ID')

    def handle(self, *args, **kwargs):
        users_ids = kwargs['user_id']

        for user_id in users_ids:
            try:
                user = User.objects.get(pk=user_id)
                user.delete()
                self.stdout.write('User "%s (%s)" deleted with success!' % (user.username, user_id))
            except User.DoesNotExist:
                self.stdout.write('User with id "%s" does not exist.' % user_id)

See how we named our module create_users.py. This command can be executed as:

Output
python manage.py delete_users 1

or

User "1uTOXo4kyQOn (1)" deleted with success!

We can also pass a number of ids separated by spaces, so the command will delete the users in a single call:

python manage.py delete_users 1 2 3
Output
User with id "1" does not exist.
User "TBYyzwCA8NBZ (2)" deleted with success!
User "VkasoEK0YYE2 (3)" deleted with success!
User "Yh83nwRgJrTY (4)" deleted with success!
Cron Job

Here, i will show you how to setup cron job command on server. let’s say you have a Web scrapper that collects data from some Website every 10 minutes. so let's run bellow command and add new entry for cron job.

# m h  dom mon dow   command
0 4 * * * /home/mysite/venv/bin/python /home/mysite/mysite/manage.py my_command

I hope it will help you....