django-extensionsの runscript コマンドでスクリプトを実行する

django-extensionsには、スクリプトファイルを実行するための runscript というコマンドが用意されている。

このコマンドを使うと、Djangoのコンテキスト(つまり、Djangoのsettings.pyが適用された、 django.setup() を実行済みの状態)で、Pythonスクリプトを実行できる。

RunScript — django-extensions 3.2.3 documentation

試したバージョンは、Python 3.10、Django 4.2、django-extensions 3.2.3。

scriptsフォルダにスクリプトファイルを用意する

django-extensionsをセットアップ済みのプロジェクトで作業する。

Djangoのプロジェクトディレクトリに、 scripts という名前のフォルダを作成し、スクリプトファイルはその中に作成する。

scriptsフォルダ内のスクリプトPythonモジュールとして再利用しないのであれば、scriptsフォルダには __init__.py を作成しなくてもよい。

今回作成したのは、 scripts/foo.py というファイル。

ディレクトリ構造とファイルの配置は次の通り。

.
├── db.sqlite3
├── manage.py
├── myproject
│     ├── __init__.py
│     ├── asgi.py
│     ├── settings.py
│     ├── urls.py
│     └── wsgi.py
└── scripts
    └── foo.py

scripts/foo.py:

from django.contrib.auth.models import Permission

def run(*args):
    """fooという名前のスクリプト
    """
    print(f"args: {args}")
    # ORMも使える
    print(Permission.objects.count())

今回作成したファイルでは、Permissionモデルのレコード件数を取得して画面に出力している。

このコードは、DjangoのORMが使われる。

関数名は run としておく。runscriptコマンドから渡される引数は、可変長引数で受け取れる。

runscriptコマンドでスクリプトを実行する

django-extensionsをセットアップ済みのプロジェクトでは、manage.pyコマンドのサブコマンドとして runscript コマンドが使えるようになっている。

python manage.py runscript <script_name> のように、スクリプトファイル名の .py を除いた名前で実行できる。

$ python manage.py runscript foo --script-args hoge fuga
args: ('hoge', 'fuga')
24

スクリプトには、 --script-args オプションでコマンドから追加パラメータの文字列を渡すことができる。スペース区切りで複数の値を指定できる。

実行結果では、ORMが動作して、正常にcount()の結果が表示されていることがわかる。

まとめ

  • django-extensionsには、 runscript コマンドがある
  • runscript コマンドでは、Djangoのコンテキストでスクリプトファイルを実行できる
  • Djangoのプロジェクトフォルダに scripts/<script name>.py のようなファイルでスクリプトを用意する
  • python manage.py runscript <script name> --script-args param1 param2 .. のように実行する