Skip to main content

How to Create a DocType in Frappe Framework (Version 15)

Introduction — Understanding DocTypes in Frappe

A DocType in the Frappe Framework defines the structure of a database table and the form interface users interact with.
It acts as the core data model in Frappe — everything from Customers, Invoices, or Employees to custom business objects are implemented as DocTypes.

Each DocType:

  • Represents a database table in MariaDB.
  • Defines fields, permissions, and behavior.
  • Can include logic through custom scripts, server scripts, or controller files.In Frappe v15, DocType creation has been made even more streamlined through improved Desk UI and simplified developer workflows.

Prerequisites for Creating a DocType in Frappe v15

Before creating a DocType, ensure the following setup is complete.

Environment Requirements

  • Frappe Framework: Version 15 (installed and running)
  • Bench CLI: Installed globally (pip install frappe-bench)
  • App Context: A Frappe app (e.g., my_app) where your DocType will reside
  • User Role: Developer access with permission to create new DocTypes

If you haven’t created an app yet:

bench new-app my_app

Then install it on your site:

bench --site site-name.localhost install-app my_app

Step-by-Step Guide — How to Create a DocType in Frappe

Creating a DocType can be done directly through the Desk UI or the command line.
Below are both approaches as per Frappe Framework v15 best practices.

Option 1: Create a DocType from the Frappe Desk

  1. Login to your Frappe site (e.g., http://site-name.localhost:8000).
  2. In the search bar, type and open “DocType List”.
  3. Click “New” to create a new DocType.

You’ll see a form with multiple fields. Fill them as follows:

Field

Description

Name

The name of your DocType (e.g., “Task Tracker”)
Module

Select the module under your app (e.g., “Projects”)

Custom?

Leave unchecked for standard DocTypes (checked for Custom DocTypes)

Is Submittable?

Enable if the document supports submission workflow

Fields Table

Define the fields your DocType will contain (Fieldname, Label, Type, etc.)
Permissions Table

Configure which roles can read/write/create this document

After entering details, Save and Reload.
Frappe automatically generates:

  • A corresponding database table (tabTask Tracker)
  • JSON and Python controller files in your app directory

Option 2: Create a DocType via Bench CLI

If you prefer working from the terminal, you can create a DocType using Bench.
Navigate to your app directory and run:

cd frappe-bench/apps/my_app
bench make-doctype "Task Tracker"

This automatically:

  • Creates the DocType folder inside my_app/my_app/doctype/
  • Adds:
    • task_tracker.json (DocType schema)
    • task_tracker.py (controller file)
    • task_tracker.js (client script placeholder)
    • __init__.py file for module imports

Example:

my_app/
└── my_app/
└── doctype/
└── task_tracker/
├── __init__.py
├── task_tracker.json
├── task_tracker.py
└── task_tracker.js

Example: Creating a “Task Tracker” DocType

Let’s create a simple Task Tracker DocType to manage project tasks.

Step 1: Run the Command

bench make-doctype "Task Tracker" --module "Projects"

Step 2: Define Fields in the JSON Schema

Open the generated file:

my_app/my_app/doctype/task_tracker/task_tracker.json

Example JSON:

{
"doctype": "DocType",
"name": "Task Tracker",
"module": "Projects",
"custom": 0,
"is_submittable": 1,
"fields": [
{
"fieldname": "task_title",
"label": "Task Title",
"fieldtype": "Data",
"reqd": 1
},
{
"fieldname": "status",
"label": "Status",
"fieldtype": "Select",
"options": "Open\nIn Progress\nCompleted"
},
{
"fieldname": "due_date",
"label": "Due Date",
"fieldtype": "Date"
}
]
}

Step 3: Migrate Changes

Once saved, apply the schema to your database:

bench migrate

This creates the tabTask Tracker table in MariaDB with the specified fields.

DocType Database Structure in Frappe

When a DocType is created, Frappe automatically:

  • Creates a MariaDB table prefixed with tab
  • Maps each field to a column
  • Adds system fields like:
    • name (Primary Key)
    • owner, creation, modified, docstatus, etc.

Example:

DESCRIBE `tabTask Tracker`;

Output:

| Field              |  Type            |  Null     | Key   | Default | Extra   |

| name              |  varchar(140)     | NO          |   PRI       | NULL   |                 |

| task_title     |  varchar(255)     |   YES       |                  | NULL    |                |

| status           |  varchar(140)      | YES         |                  | NULL    |                |

| due_date      |  date                      |   YES       |                  | NULL    |                |

| owner          |  varchar(255)      |    YES      |                  | NULL    |                |

Adding Logic to Your DocType

Server-Side Logic (Python)

In your controller file (task_tracker.py):

import frappe
from frappe.model.document import Document
class TaskTracker(Document):
def validate(self):
if self.status == "Completed" and not self.due_date:
frappe.throw("Please set a Due Date before marking as Completed")

Client-Side Logic (JavaScript)

In your client script (task_tracker.js):

frappe.ui.form.on("Task Tracker", {
refresh: function(frm) {
if (frm.doc.status === "Completed") {
frm.set_df_property("task_title", "read_only", 1);
}
}
});

Best Practices & Tips

  • Use Singular names for DocTypes (e.g., “Invoice,” not “Invoices”).
  • Keep fieldnames lowercase and snake_cased (customer_name, due_date).
  • Avoid spaces in fieldname; Frappe uses these internally as database column names.

Enable Developer Mode during development to allow file-based JSON creation:

bench set-config developer_mode 1
bench restart

  • Always run bench migrate after schema edits.
  • Use Custom Fields instead of editing Core DocTypes for maintainability.

Troubleshooting Common Errors

Permission Error: Cannot create DocType

Enable developer mode:

bench set-config developer_mode 1
bench restart

Table already exists

You might have manually deleted JSON but not dropped the table.
Drop it manually via MariaDB:

DROP TABLE `tabTask Tracker`;
bench migrate

App Not Installed

Ensure your custom app is installed on the active site:
bench --site site-name.localhost install-app my_app

Cross-References and Related Guides

Click to rate this post!
[Total: 1 Average: 5]