doctype-development について
Frappe の中核となるデータモデル DocType を作成・変更する開発者向けスキルです。フィールド、コントローラー、命名、権限、ワークフローやスキーマ変更の確認を扱います。
主な機能
- 01DocType の種類選定
- 02フィールドとスキーマの定義
- 03コントローラーのライフサイクル処理
- 04命名シリーズの設定
- 05ロール権限とワークフロー
- 06マイグレーションと検証
活用シーン
- 01新しい DocType の作成
- 02既存 DocType へのフィールド追加
- 03検証処理とライフサイクルフックの実装
- 04レコードアクセスと承認フローの設定
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ lubusin/ frappe-skills --skill doctype-developmentインストール後、Claude Code で/doctype-developmentを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/child-tables.mdcontrollers.mddoctypes.mdfield-types.mdhooks-extensions.mdnaming.mdpermissions.mdvirtual-doctypes.md詳細
Frappe DocType の開発
Frappe Framework の中核となるデータモデル抽象化である DocType を作成、変更します。
使用する場面
- 新しい DocType の作成(標準、シングル、子テーブル、サブミット可能、ツリー)
- 既存の DocType へのフィールドの追加や変更
- コントローラーロジックの実装(validate、before_save、on_submit など)
- 命名シリーズと自動命名の設定
- 権限とワークフローの設定
- 子テーブルと親子関係の構築
必要な入力
- 対象アプリとモジュールパス
- DocType 名と種類(standard/single/child/submittable/tree)
- フィールド定義(名前、種類、オプション)
- ロールごとの権限要件
- ワークフローが必要かどうか
手順
0) 環境を確認する
# Ensure developer mode is enabled
bench --site <site> console
>>> frappe.conf.developer_mode # Must be True
1) DocType の種類を選ぶ
| 種類 | 用途 | 主な設定 |
|---|---|---|
| 標準 | 複数レコード | デフォルト |
| シングル | 設定(1 レコード) | issingle: 1 |
| 子テーブル | 親テーブル内の行 | istable: 1 |
| サブミット可能 | 下書き→サブミット→キャンセルのワークフロー | is_submittable: 1 |
| ツリー | 階層データ | is_tree: 1 |
| 仮想 | 外部データソース | is_virtual: 1 |
2) DocType を作成する
オプション A:UI 経由(新しい DocType の作成に推奨)
- DocType List → New に移動します
- フィールド、権限、設定を定義します
- 保存します(開発者モードではアプリにエクスポートされます)
オプション B:コード経由
# Create DocType JSON in:
# <app>/<module>/doctype/<doctype_name>/<doctype_name>.json
3) フィールドを定義する
一般的なフィールドパターン:
{
"fieldname": "customer",
"fieldtype": "Link",
"label": "Customer",
"options": "Customer",
"reqd": 1
}
すべてのフィールド種類については、references/field-types.md を参照してください。
4) コントローラーを実装する
JSON ファイルと同じ場所に <doctype_name>.py を作成します。
import frappe
from frappe.model.document import Document
class MyDocType(Document):
def validate(self):
# Lightweight validation
if not self.customer:
frappe.throw("Customer is required")
def before_save(self):
# Pre-save normalization
self.full_name = f"{self.first_name} {self.last_name}"
def after_insert(self):
# Post-create side effects
frappe.publish_realtime("new_doc", {"name": self.name})
5) 命名を設定する
{
"autoname": "naming_series:",
"fields": [
{
"fieldname": "naming_series",
"fieldtype": "Select",
"options": "PRJ-.YYYY.-\nPRJ-.YYYY.-.###"
}
]
}
オプション:field:fieldname、naming_series:、hash、format:PREFIX-{####}
6) 権限を設定する
DocType → Permissions タブで設定します。
- ロール + Read/Write/Create/Delete/Submit/Cancel
- 行レベルのフィルタリング用のユーザー権限
7) ワークフローを追加する(必要な場合)
状態と遷移を設定した Workflow DocType を作成し、対象の DocType に関連付けます。
検証
- DocType が一覧に表示され、新しいレコードを作成できる
- すべてのフィールドが正しく保存される
- コントローラーのフックが実行される(ログを確認)
- 各ロールに権限が適用される
- 命名シリーズが正しく生成される
-
bench --site <site> migrateが成功する
失敗時の対処/デバッグ
- DocType が見つからない:モジュールパスとアプリのインストール状況を確認します
- コントローラーが読み込まれない:クラス名が DocType 名(PascalCase)と一致していることを確認します
- フィールドが保存されない:fieldtype と options の互換性を確認します
- 権限が拒否される:ロール権限とユーザー権限を確認します
エスカレーション
- 複雑な権限ロジックについては、references/permissions.md を参照してください
- 子テーブルのパターンについては、references/child-tables.md を参照してください
- 仮想 DocType については、references/virtual-doctypes.md を参照してください
参考資料
- references/field-types.md - すべてのフィールド種類とオプション
- references/controllers.md - コントローラーのライフサイクルフック
- references/child-tables.md - 親子関係のパターン
- references/naming.md - 命名パターン
ガードレール
- スキーマ変更の前に developer_mode を確認する:DocType の変更がファイルにエクスポートされるのは、サイト設定で
developer_mode = 1の場合のみです - 命名シリーズの一意性を確認する:命名シリーズのプレフィックスが既存の DocType と競合しないことを確認します
- 子テーブルを個別にテストする:子テーブルには独自のライフサイクルがあるため、親との統合前に単独でテストします
- 変更後は必ず migrate を実行する:スキーマ変更の適用には
bench --site <site> migrateが必要です - fieldname の規則を検証する:snake_case を使用し、最大 140 文字とし、予約済みの SQL キーワードは使用しません
よくある間違い
| 間違い | 失敗する理由 | 修正方法 |
|---|---|---|
必須フィールドに reqd がない | ユーザーが不完全なデータを保存できます | 値が必須のフィールドに reqd: 1 を設定します |
| データに適さないフィールドタイプ | データの切り詰めや検証エラーが発生します | データに合ったフィールドタイプを選びます(例:金額には Float ではなく Currency) |
bench migrate を実行しない | データベースにスキーマ変更が適用されません | DocType を変更した後は必ず bench --site <site> migrate を実行します |
| Link の循環依存関係 | DocType の作成に失敗します | Dynamic Link を使うか、関係を再構成します |
| コントローラーのクラス名が一致しない | コントローラーのメソッドが呼び出されません | クラス名は DocType 名をパスカルケースにしたものにする必要があります(例:「Sales Order」には SalesOrder) |
重要なフィールドに in_list_view がない | リストにフィールドが表示されません | 重要なフィールドに in_list_view: 1 を設定します |
コメント
Markdown 対応