ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
なぜ Django のカスタム管理コマンドが必要なのか
cron で python my_script.py を直接叩くと、django の設定(settings.py)が読み込まれず、ORM 経由でモデルを触ろうとした瞬間に django.core.exceptions.ImproperlyConfigured で落ちます。
Django のお作法に則り 「カスタム管理コマンド(custom management command)」 として実装すると、manage.py がプロジェクトを正しく初期化してくれるため、モデル・キャッシュ・メール送信などのフル機能をそのまま使えます。
1. ディレクトリ構成
対象アプリの下に以下のフォルダ階層を作ります。__init__.py を忘れずに置くのがポイントです(空ファイルで OK)。
myapp/
├── __init__.py
├── models.py
├── views.py
└── management/
├── __init__.py ← 必須
└── commands/
├── __init__.py ← 必須
└── my_command.py ← ここがコマンド本体
ファイル名がそのままコマンド名になります。my_command.py なら python manage.py my_command で呼べます。
2. 最小コマンドの実装
my_command.py 内では BaseCommand を継承した Command クラスを定義し、handle() に処理を書きます。
# myapp/management/commands/my_command.py
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = "Hello World を出力するサンプルコマンド"
def handle(self, *args, **options):
self.stdout.write("Hello World!")
実行は以下のとおり。
python manage.py my_command
# => Hello World!
# 一覧確認(自作コマンドが MyApp グループに出る)
python manage.py help
3. 引数オプションを受け取る
add_arguments(self, parser) をオーバライドして argparse 形式で引数を定義します。受け取った値は handle の options 辞書から取り出せます。
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = "ユーザを指定回数あいさつする"
def add_arguments(self, parser):
# 位置引数
parser.add_argument("name", type=str)
# オプション引数
parser.add_argument(
"--times",
type=int,
default=1,
help="繰り返し回数(既定: 1)",
)
parser.add_argument(
"--shout",
action="store_true",
help="大文字にする",
)
def handle(self, *args, **options):
name = options["name"]
times = options["times"]
shout = options["shout"]
msg = f"Hello, {name}!"
if shout:
msg = msg.upper()
for _ in range(times):
self.stdout.write(msg)python manage.py greet Taro --times 3 --shout
# => HELLO, TARO!
# => HELLO, TARO!
# => HELLO, TARO!
4. モデルを使った実用コマンド
cron で「30 日経過した一時データを削除」のような典型バッチを書く例です。
# myapp/management/commands/cleanup_old.py
from datetime import timedelta
from django.core.management.base import BaseCommand
from django.utils import timezone
from myapp.models import TempData
class Command(BaseCommand):
help = "30 日経過した TempData を削除する"
def add_arguments(self, parser):
parser.add_argument("--days", type=int, default=30)
parser.add_argument("--dry-run", action="store_true")
def handle(self, *args, **options):
days = options["days"]
dry_run = options["dry_run"]
threshold = timezone.now() - timedelta(days=days)
qs = TempData.objects.filter(created_at__lt=threshold)
count = qs.count()
if dry_run:
self.stdout.write(self.style.WARNING(
f"[dry-run] {count} 件削除対象"))
return
deleted, _ = qs.delete()
self.stdout.write(self.style.SUCCESS(
f"{deleted} 件削除しました"))
5. cron への登録
OS 標準の cron から呼ぶ場合、仮想環境の Python と プロジェクトディレクトリ を明示するのが鉄則です。PATH に依存しないフルパスで書きます。
# crontab -e で開いて以下を追記
# 毎日 03:30 に cleanup_old を実行
30 3 * * * cd /var/www/myproject && /var/www/myproject/.venv/bin/python manage.py cleanup_old >> /var/log/myproject/cron.log 2>&1
| ポイント | 理由 |
|---|---|
| 仮想環境の Python をフルパスで指定 | cron 環境では which python が想定と違う可能性 |
cd でプロジェクトディレクトリへ移動 | manage.py 起動時の作業ディレクトリを固定(settings 読み込み) |
| 標準出力・標準エラーをログにリダイレクト | 失敗原因を後から追える(2>&1 で stderr も同じファイルへ) |
環境変数(DJANGO_SETTINGS_MODULE など)も必要なら crontab で設定 | cron はログインシェルではないため、シェルで設定した env が読まれない |
6. django-crontab / django-q / Celery beat という選択肢
OS の cron に直接登録する以外に、Python 側で完結させる選択肢もあります。
| ツール | 特徴 |
|---|---|
| django-crontab | settings.py にスケジュールを書くだけで OS cron に同期。シンプル |
| django-q / django-q2 | 非同期タスクキュー。スケジュール + リトライ + 並列ワーカ |
| Celery + Celery beat | 本格的な非同期ジョブシステム。Redis / RabbitMQ をブローカに使う |
| OS cron + manage.py | 外部依存ゼロ。小規模なら最もシンプル(本記事の方法) |
よくあるハマりどころ
| 症状 | 原因 / 対処 |
|---|---|
Unknown command と言われる | ファイル配置ミス / __init__.py 抜け / アプリが INSTALLED_APPS に未登録 |
| cron で動かないがシェルでは動く | cron は最小限の環境変数しか持たない。crontab に PATH= や DJANGO_SETTINGS_MODULE= を明示 |
| ログが残らない | 標準出力をファイルへリダイレクトしていない。>> /var/log/.../cron.log 2>&1 を付ける |
| 重複起動 | 処理が長引き次の起動が被る。flock で排他制御するか、ジョブ側で in-progress フラグを持つ |
関連
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページはありません
- 環境構築とプロジェクト/アプリの作成
- MVC(MVT)のそれぞれの使い方と説明
- データベースへの接続と操作
- Django Administration
- git管理
- エラー一覧
- バージョンの確認方法
- ログ出力方法
- SQLのログ出力方法
- ログのローテート設定
- settings.pyの定数にアクセスする方法
- 本番環境へのインストールとアプリのデプロイ(apache編)
- 本番環境へのインストールとアプリのデプロイ(nginx編)
- djangoアプリの本番の開始URLを変更する
- 静的(static)ファイルの置き場所と読み込み(画像、css、js )
- CSRFトークンをAjaxで使用する方法
- ajaxの使用例(POST編)
- ファイルのアップロードとファイルの名前
- クイックスタート/チュートリアル
- ログイン機能
- テンプレート側のログイン判定
- ビュー側のログイン判定
- 管理者ユーザーの作成/判定と管理画面
- モデルのjson化とレスポンス
- runserverでポートを指定する方法
- cronによるバッチ実行
- テンプレートで利用する共通のcontextを定義する方法
- プログラムが本番サーバーで反映されない場合の対処法
- APIの作成
- cron用コマンド・ファイルの作成
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- IPv6とは|128bitアドレス・コロン16進表記/::省略・リンクローカル・SLAAC・デュアルスタック NEW 2026-06-22 12:34:44
- MAC アドレスフィルタリングの仕組みと限界 | ネットワーク入門 NEW 2026-06-22 12:19:10
- VPNとは|暗号トンネル・サイト間/リモートアクセス・IPsec/SSL-VPN/WireGuardを解説 NEW 2026-06-22 12:19:10
- WebRTC とは ブラウザ間 P2P の音声・映像・データ通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/2 とは 多重化・HPACK・バイナリフレーム | ネットワーク入門 NEW 2026-06-22 12:17:25
- Web通信プロトコル入門 HTTP/2・HTTP/3・WebSocket・gRPC・WebRTC | ネットワーク入門 NEW 2026-06-22 12:17:25
- gRPC とは HTTP/2 + Protocol Buffers の高速 RPC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/3 (QUIC) とは UDP ベースの低遅延 Web 通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebSocket とは 全二重リアルタイム通信 ws/wss | ネットワーク入門 NEW 2026-06-22 12:17:25
- 証明書と認証局(CA)とは|X.509・信頼チェーン・DV/OV/EV・失効(CRL/OCSP)を解説 NEW 2026-06-22 12:17:24
- ファイアウォールとは|パケットフィルタ・ステートフル・DMZ・次世代FW(L4/L7)を解説 NEW 2026-06-22 12:17:24
- iptables/nftablesとは|テーブル・チェーン・ルール例・永続化をLinux視点で解説 NEW 2026-06-22 12:17:24
- HAProxy とは frontend/backend と設定例 | ネットワーク入門 NEW 2026-06-22 12:17:24
- CDN とは エッジキャッシュ・TTL・Cloudflare/CloudFront | ネットワーク入門 NEW 2026-06-22 12:17:24
- TLS/SSLの仕組み|ハンドシェイク・暗号スイート・前方秘匿性・証明書検証をわかりやすく解説 NEW 2026-06-22 12:17:24
コメントを削除してもよろしいでしょうか?