カスタム django-admin コマンドを実装して、外部からアプリ内のモデルを使う

背景

cronを使ったバッチ処理などで、アプリ内のモデルを使ってDBを読み書きしたい場合があります。
しかし、コマンド用の.pyファイルを上位ディレクトリに置いて、アプリ内のモデルをimportして使おうとすると、ValueError: attempted relative import beyond top-level package とエラーが出て、アプリのディレクトリ外からは呼び出せません。

そこで、カスタム django-admin コマンドとして実装します。

詳しくは、公式ドキュメントの「カスタム django-admin コマンドの実装」に解説があります。

環境は、Python 3.7.0、Django 2.1.3 です。 

作成手順

  • アプリ内に、maangement/commands ディレクトリを作成する
  • その中に、コマンド名.pyを作成する(以下では、crawler.py)

以下のようなフォルダ構成になります。

├── app1
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── management
│   │   └── commands
│   │       └── crawler.py ★これ
│   ├── models.py
│   ├── urls.py
│   └── views.py
├── myproject
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py
  • コマンド名.pyの中身を記述する
from django.core.management.base import BaseCommand, CommandError
from app1.models import Topic

class Command(BaseCommand):
  help = 'crawler for test.'

  def handle(self, *args, **options):
    t = Topic.objects.all()
    self.stdout.write(self.style.SUCCESS("all Topic=%s" % t))
  • 詳細
    • from django.core.management.base import BaseCommand, CommandError
    • handleメソッドに、実行したい内容を記述
    • モデルもimportして利用できる
    • 文字列を出力したい場合は、self.stdout経由で出力
    • help変数に説明を記述

確認

  • $ python manage.py helpで表示されるコマンド一覧に、追加したコマンドが表示される
Type 'manage.py help ' for help on a specific subcommand.

Available subcommands:

[auth]
    changepassword
    createsuperuser

[app1]
    crawler
(略)
  • $ python manage.py help crawlerで、作成したコマンドのヘルプが表示される
usage: manage.py crawler [-h] [--version] [-v {0,1,2,3}]
                         [--settings SETTINGS]
                         [--pythonpath PYTHONPATH] [--traceback]
                         [--no-color]

crawler for test.

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.
  • $ python manage.py crawlerで、実行する
all Topic=]>

バージョン??

ヘルプで出るように、$ python manage.py crawler --versionでバージョンが表示されますが、何も定義しないと、Djangoのバージョンが表示されるようです。

公式ドキュメント

カスタム django-admin コマンドに、独自引数を追加する

続きを書きました。カスタム django-admin コマンドに、独自引数を追加する

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です