LoginSignup
2

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-12-05

背景

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の中身を記述する
crawler.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 <subcommand>' 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=<QuerySet [<Topic: テスト記事1>]>

バージョン??

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

公式ドキュメント

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

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

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
2