[PYTHON] Create custom Django commands and run them from the command line

Create custom Django commands to run from the command line

Introduction

When developing a web application, you may want to perform specific processing (aggregation processing, API call, mail delivery, etc.) from the command line. This article will show you how to write a process to run a Django application from the command line.

Django command line tools

By default, Django comes with command-line tools that allow you to do things like the following from the command line:

python manage.py startapp sample =>Creating an application
python manage.py migrate         =>Executing DB migration
python manage.py shell           =>Launching an interactive shell
python manage.py runserver       =>Start development server

There are many other commands available, and you can type python manage.py to see a list of available commands.

% python manage.py      

Type 'manage.py help <subcommand>' for help on a specific subcommand.

Available subcommands:

[auth]
    changepassword
    createsuperuser

[debug_toolbar]
    debugsqlshell

[django]
    check
    compilemessages
    createcachetable
    dbshell
    diffsettings
    dumpdata
    flush
    inspectdb
    loaddata
    makemessages
    makemigrations
    migrate
    sendtestemail
    shell
    showmigrations
    sqlflush
    sqlmigrate
    sqlsequencereset
    squashmigrations
    startapp
    startproject
    test
    testserver

[sessions]
    clearsessions

[staticfiles]
    collectstatic
    findstatic
    runserver

For more detailed help for a particular command, type help followed by the name of the command you want to reference, such as python manage.py help runserver.

% python manage.py help runserver     
usage: manage.py runserver [-h] [--version] [-v {0,1,2,3}]
                           [--settings SETTINGS] [--pythonpath PYTHONPATH]
                           [--traceback] [--no-color] [--ipv6] [--nothreading]
                           [--noreload] [--nostatic] [--insecure]
                           [addrport]

Starts a lightweight Web server for development and also serves static files.

positional arguments:
  addrport              Optional port number, or ipaddr:port

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  -v {0,1,2,3}, --verbosity {0,1,2,3}
                        Verbosity level; 0=minimal output, 1=normal output,
                        2=verbose output, 3=very verbose output
  --settings SETTINGS   The Python path to a settings module, e.g.
                        "myproject.settings.main". If this isn't provided, the
                        DJANGO_SETTINGS_MODULE environment variable will be
                        used.
  --pythonpath PYTHONPATH
                        A directory to add to the Python path, e.g.
                        "/home/djangoprojects/myproject".
  --traceback           Raise on CommandError exceptions
  --no-color            Don't colorize the command output.
  --ipv6, -6            Tells Django to use an IPv6 address.
  --nothreading         Tells Django to NOT use threading.
  --noreload            Tells Django to NOT use the auto-reloader.
  --nostatic            Tells Django to NOT automatically serve static files
                        at STATIC_URL.
  --insecure            Allows serving static files even if DEBUG is False.

Create custom Django commands

Django's command-line tools provide a mechanism for adding commands. Once you have added a custom command, you can run it from a command line tool as follows:

python manage.py <Custom command name>

sample

This time, let's add a custom command to this Blog management application and execute it. Please check the contents of the linked Github for the final source code.

The structure of the blog directory of the blog management application is as follows.

├── blog
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── forms.py
│   ├── migrations/
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── django_sample/
├── manage.py
└── requirements.txt

Creating a directory

First, create a directory (management / commands) for storing commands under the blog application.

mkdir -p blog/management/commands
touch blog/management/__init__.py
touch blog/management/commands/__init__.py  

Creating a command

Next, create count_entry.py, which is the main body of the command, in the created directory (management / commands /).

vi blog/management/commands/count_entry.py

Custom commands inherit from the BaseCommand class to create a class. The actual processing body is described in the handle method. This time, we will create a program that displays the number of blog articles passed as an argument.

count_entry.py


# -*- coding:utf-8 -*-


from django.core.management.base import BaseCommand

from ...models import Article


#Created by inheriting BaseCommand
class Command(BaseCommand):
    # python manage.py help count_Message displayed by entry
    help = 'Display the number of blog articles'

    #Specify command line arguments.(argparse module https://docs.python.org/2.7/library/argparse.html)
    #This time blog_Get it with the name id. (At least one argument,int type)
    def add_arguments(self, parser):
        parser.add_argument('blog_id', nargs='+', type=int)

    #Method called when the command is executed
    def handle(self, *args, **options):
        for blog_id in options['blog_id']:
            articles_count = Article.objects.filter(blog_id=blog_id).count()

            self.stdout.write(self.style.SUCCESS('Article count = "%s"' % articles_count))

The final directory structure is as follows.

blog
├── __init__.py
├── admin.py
├── apps.py
├── forms.py
├── management =>Directory for storing custom commands
│   ├── __init__.py
│   └── commands
│       ├── __init__.py
│       └── count_entry.py
├── migrations/
├── models.py
├── tests.py
├── urls.py
└── views.py

Executing custom commands

Let's execute the created custom command. First run python manage.py to see if any custom commands have been added.

% python manage.py 

Type 'manage.py help <subcommand>' for help on a specific subcommand.

Available subcommands:

[auth]
    changepassword
    createsuperuser

[blog]
    count_entry =>Has been added

[debug_toolbar]
    debugsqlshell

[django]
    check
    compilemessages
    createcachetable
    dbshell
    diffsettings
    dumpdata
    flush
    inspectdb
    loaddata
    makemessages
    makemigrations
    migrate
    sendtestemail
    shell
    showmigrations
    sqlflush
    sqlmigrate
    sqlsequencereset
    squashmigrations
    startapp
    startproject
    test
    testserver

[sessions]
    clearsessions

[staticfiles]
    collectstatic
    findstatic
    runserver

The count_entry command has been added. Then type python manage.py count_entry 1 to run the custom command you created.

% python manage.py count_entry 1
Article count = "2"

A custom command was executed and the number of blog posts was displayed. You can also use the help command as you would a regular Django command. The created command can be executed regularly by using cron etc. like a normal script.

At the end

This time, I introduced how to create a custom command that can be executed from Django's command line tools. I think there are many cases where you create your own command, such as when you want to execute processing regularly with cron. Why not create a custom Django command and take advantage of it? Have a fun Django life!

Reference site

Recommended Posts

Create custom Django commands and run them from the command line
How to create an article from the command line
Dive into the Django Custom command [1]
[EC2] How to install and download chromedriver from the command line
Open Chrome version of LINE from the command line [Linux]
DJango Note: From the beginning (simplification and splitting of URLConf)
Search for large files on Linux from the command line
Twitter post from command line
Create and list Django models
Organize [Django] commands and roles
Install Chrome on the command line on Sakura VPS (Ubuntu) and launch Chrome with python from virtual display and selenium
Run Pylint and read the results
DJango Memo: From the beginning (preparation)
Get the value from the [Django] Form
Create Splunk custom search command Part 2
Create a LINE Bot in Django
Get, test, and submit test cases on the command line in the AtCoder contest
Get options in Python from both JSON files and command line arguments
Deploy Django + React from scratch to GKE (4) Create cluster and container PUSH
Get news from three major mobile companies using Django and the News API
Create a command to search for similar compounds from the target database with RDKit and check the processing time