LoginSignup
4
11

More than 3 years have passed since last update.

【Django】開発に地味に便利なスクリプト集

Posted at

Djangoの開発ではcliを叩くことが多くなりがちですが、
オプションとか覚えてられないかつ面倒なので、よくPipenv等のタスクランナー機能を用います。
私はpoetry派なのでpoetry scriptsをよく使います。(poetryはタスクランナー機能という名目でscripts機能を実装していないことに留意)

また、django_extensionsを用いれば、欲しい機能もすでに使用可能なことが多いです。

過去の投稿でも、runserverを行うスクリプトを紹介しました。
【Poetry】Poetry script で Django の runserver を起動 - Qiita
今回はこの他に、自分のプロジェクトで使っているスクリプトを紹介します。

環境

  • Python 3.7.4
  • poetry 1.0.5
  • django-extensions 2.2.8

django-extensions

django-extensionsは、Django開発用のアプリケーションで、様々な便利機能を用意してくれるパッケージです。
django-extensionsをインストールし、INSTALLED_APPSに追加しておきます。

$ pip install django-extensions
INSTALLED_APPS = [
    ...
    'django_extensions', # 追加
]

scripts

私はパッケージ管理にPoetryを使用しているので、poetry scriptsを使用しています。
poetry scriptsを利用する利点として、仮想環境外で実行しても、一度仮想環境内に入り、仮想環境内でタスクを実行してくれる点があります。
テストだけ確認したい、URLだけ一覧表示したいという時や、仮想環境に関して理解がない人も一行のコマンドで実行出来るのは侮れません。

以前の投稿と同じく、subprocessパッケージを利用してコマンド実行を行います。

shell_plus

django-extensionsといえばの機能で、shell_plusという機能があります。
Django shellを拡張しており、補完や事前インポート等を行ってくれ、かなり便利です。

def shell_plus():
    cmd = ["python", "manage.py", "shell_plus"]
    subprocess.run(cmd)

URLを表示

django-extensionsには、DjangoアプリケーションのすべてのURLを出力をする機能があります。
APIドキュメントの作成時などかなり重宝します。
--formatオプションでは、出力形式を変更出来ます。

def url():
    cmd = ["python", "manage.py", "show_urls", "--format", "aligned", "--force-color"]
    subprocess.run(cmd)

ソース内のTODOを表示

django-extensionsのnotes機能を用いれば、
pyファイルとHTMLファイル内のTODO, FIXME, BUG, HACK, WARNING, NOTEなどを抽出し、一覧表示してくれます。
これが地味に便利で、一日の始めのTODO確認をCLIでできるのが良いです。
ファイルへのPathも表示されるので、VSCodeであればCtrl + クリックでそのまま開けます。

def todo():
    cmd = ["python", "manage.py", "notes"]
    subprocess.run(cmd)
  • 出力
$ python manage.py notes
/home/user/workspace/app/web/views.py:
  * [ 18] TODO  sort filter

/home/user/workspace/app/web/models.py:
  * [ 11] TODO  例外処理

/home/user/workspace/app/web/forms.py:
  * [ 32] TODO  バリデーション追加

テストを実行

Djangoのテスト機能には、並列実行機能があります。
勿論その実行数にはCPUのコア数が関わってくるのですが、コア数は環境によって異なります。
multiprocessing.cpu_count()を用い、動的にコア数を取得してテストの並列実行を行います。
-vはverboseです。

import multiprocessing

def test():
    core_num = multiprocessing.cpu_count()
    # core_numとすると、subprocessが一つの実行プロセスとなるため、テストが上手く動かない。
    cmd = ["python", "manage.py", "test", "--force-color", "-v", "2", "--parallel", f"{core_num - 1}"]
    subprocess.run(cmd)

マイグレーションファイルを削除

データベースリセット時には、マイグレーションファイルをすべて消去します。
開発初期にはそこそこの頻度で行うので、削除スクリプトを作成しておくのが楽です。

import os
import glob

BASE_DIR = os.path.dirname(os.path.dirname(__file__)) # このファイルの場所によって変更

def clean_migration():
    migration_files = glob.iglob('**/migrations/[0-9][0-9][0-9][0-9]*.py', recursive=True)
    for migration_file in migration_files:
        os.remove(os.path.join(BASE_DIR, migration_file))
        print(f"Deleted {migration_file}")

データベースのリセット

データベースの削除と再作成を1コマンドで行う機能が、django-extensionsに用意されています。

def reset_db():
    cmd = ["python", "manage.py", "reset_db"]
    subprocess.run(cmd)

ER図の生成

django-extensionsの機能を用いると、ER図をmodel定義から自動生成してくれます。
この機能を用いるには、GraphvizおよびPython用アダプタpygraphvizが必要ですが、
1コマンドで最新のER図を作成してくれるのは最高です。

def graph():
    cmd = ["python", "manage.py", "graph_models", "-a", "-g", "-o",  "--arrow-shape", "normal", "graph.png"]
    subprocess.run(cmd)

models.pyのあるアプリ名表示

models.pyの存在するアプリ名を表示します。
大したコードではないですが、makemigrationsを行う際チェックする時に役立ちます。
python manage.py startapp appとしているディレクトリ構成で、モデルを記述しないアプリはmodels.pyを削除する必要があります。

import glob

def main():
    model_files = glob.iglob('**/models.py', recursive=True)

    for model_file in model_files:
        path_split = model_file.split("/")
        print(path_split[-2])

これらに加え、django runserverを強化するrunserver_plus、admin.pyを自動生成してくれるadmin_generator等がありますが、自分自身使用したことがないため一覧にはありません。

4
11
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
4
11