DEV Community

Cover image for Custom Commands in Django
JMG
JMG

Posted on

Custom Commands in Django

Hello there! We are going to learn how to write simple custom Django commands. I will break down this lesson into 3 sections;

  • Introduction
  • Setting up the commands
  • Calling the commands

Introduction

  • Create a generic Django project called resource_center.
  • Make migrations and migrate your database.
  • Create a Django app called books. Register this app in settings.py
  • In your book/models.py create a model Book as shown below;
# books/models.py

from django import models

class Book(models.Model):
    name = models.CharField(max_length=50)
    author = models.CharField(max_length=20)

Enter fullscreen mode Exit fullscreen mode
  • Make migrations and migrate your database.

Setting Up Commands

Django convention dictates that custom commands have to live inside the project/app/management/commands directory of your project. In this case, this will be resource_center/management/commands.
Navigate to your books folder and create a folder named management. Create a subfolder called commands.
Create a file inside the commands folder and name it books_creator.py.
Add the following code;

# resource_center/books/management/commands/books_creator.py
from django.core.management.base import BaseCommand
from resource_center.books.models import Book


class Command(BaseCommand):
    help = "Create initial data for the project"

    def add_arguments(self, parser):
        # Positional arguments
        parser.add_argument("count", help="Any number", type=int)

        # Named (optional) arguments
        parser.add_argument(
            "--delete",
            help="Delete books instead of creating them",
        )

    def handle(self, *args, **kwargs):
        count = kwargs.get("count")
        print(f"The current count is {count}")
        if kwargs["delete"]:
            Book.objects.all().delete()
        else:
            Book.objects.get_or_create(
                name="The Lord of the Rings",
                author="J.R.R. Tolkien"
            )
            Book.objects.get_or_create(
                name="The Hobbit",
                author="J.R.R. Tolkien"
            )


Enter fullscreen mode Exit fullscreen mode

Our class Command inherits from Django's BaseCommand.
The class variable help describes what the custom command aims to achieve, more like the help_text in your model fields.

The method add_arguments is used to instruct the command to expect arguments which may be optional.

The method handle handles (pun intended 😅) your logic.

Calling the commands

To call your commands, call them in the following format;
python manage.py <custom_command_file_name>. Do not include the file's .py extension.
In this case, our command will be called as

python manage.py books_creator <count>

The count is any number of your choice. This is a positional argument that we can not ignore. If ignored, it will raise the following error; manage.py books_creator: error: the following arguments are required: count.

The command with our count positional argument will be as follows;
python manage.py books_creator 16

If you add the optional named arguments, you get a command like this;
python manage.py books_creator 16 --delete=true

That's it!

Top comments (0)