118
95

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

DjangoAdvent Calendar 2016

Day 20

Djangoのカスタムコマンドを作成してコマンドラインから実行する

Posted at

Djangoのカスタムコマンドを作成してコマンドラインから処理を実行する

はじめに

Webアプリケーションの開発を行っていると、コマンドラインから特定の処理(集計処理、API呼び出し、メール配信など)を実行したい場合があります。この記事ではDjangoアプリケーションをコマンドラインから実行する処理の書き方を紹介します。

Djangoのコマンドラインツール

Djangoにはデフォルトでコマンドラインツールが付属しており、例えば次のような処理をコマンドラインから実行することができます。

python manage.py startapp sample => アプリケーションの作成
python manage.py migrate         => DBマイグレーションの実行
python manage.py shell           => インタラクティブShellの起動
python manage.py runserver       => 開発サーバーの起動

この他にも様々なコマンドが用意されておりpython manage.pyとタイプすると、使用できるコマンドの一覧を表示できます。

% 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

より詳細に特定のコマンドのヘルプを参照するにはpython manage.py help runserverのようにhelpに続けて参照したいコマンドの名称を入力します。

% 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.

Djangoのカスタムコマンドの作成

Djangoのコマンドラインツールには、コマンドを追加するための仕組みが用意されています。カスタムコマンドを追加すると、次のようにコマンドラインツールから実行することができます。

python manage.py <カスタムコマンド名>

サンプル

今回はこちらのブログ管理アプリケーションにカスタムコマンドを追加し、実行してみましょう。最終的なソースコードはリンク先のGithubの内容を確認してください。

ブログ管理アプリケーションのblogディレクトリの構成は以下の通りです。

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

ディレクトリの作成

まずはblogアプリケーション配下に、コマンドを格納するためのディレクトリ(management/commands)を作成します。

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

コマンドの作成

次に作成したディレクトリ(management/commands/)にコマンド本体となるcount_entry.pyを作成します。

vi blog/management/commands/count_entry.py

カスタムコマンドはBaseCommandクラスを継承してクラスを作成します。実際の処理本体はhandleメソッド内に記載します。今回は引数で渡されたブログの記事数を表示するプログラムを作成します。

count_entry.py
# -*- coding:utf-8 -*-


from django.core.management.base import BaseCommand

from ...models import Article


# BaseCommandを継承して作成
class Command(BaseCommand):
    # python manage.py help count_entryで表示されるメッセージ
    help = 'Display the number of blog articles'

    # コマンドライン引数を指定します。(argparseモジュール https://docs.python.org/2.7/library/argparse.html)
    # 今回はblog_idという名前で取得する。(引数は最低でも1個, int型)
    def add_arguments(self, parser):
        parser.add_argument('blog_id', nargs='+', type=int)

    # コマンドが実行された際に呼ばれるメソッド
    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))

最終的なディレクトリ構成は次の通りです。

blog
├── __init__.py
├── admin.py
├── apps.py
├── forms.py
├── management => カスタムコマンドを格納するディレクトリ
│   ├── __init__.py
│   └── commands
│       ├── __init__.py
│       └── count_entry.py
├── migrations/
├── models.py
├── tests.py
├── urls.py
└── views.py

カスタムコマンドの実行

作成したカスタムコマンドを実行してみましょう。はじめにpython manage.pyを実行して、カスタムコマンドが追加されているか確認します。

% python manage.py 

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

Available subcommands:

[auth]
    changepassword
    createsuperuser

[blog]
    count_entry => 追加されている

[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

count_entryコマンドが追加されています。次にpython manage.py count_entry 1と入力し、作成したカスタムコマンドを実行します。

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

カスタムコマンドが実行され、ブログの記事数が表示されました。また通常のDjangoのコマンドと同様にhelpコマンドも使用することができます。作成されたコマンドは通常のスクリプトと同じように、cronなどを利用して定期的に実行することも可能です。

終わりに

今回はDjangoのコマンドラインツールから実行できるカスタムコマンドの作成方法をご紹介しました。cronなどで定期的に処理を実行したい場合など、独自のコマンドを作成するケースはたくさんあると思います。ぜひDjangoのカスタムコマンドを作成し、活用してみてはいかがでしょうか。それでは楽しいDjangoライフを!

参考サイト

118
95
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
118
95

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?