Framework Git

Framework Git

Open in ChatGPT
Ask ChatGPT about this page
Open in Claude
Ask Claude about this page

DocTypes & the Data Model

A DocType is the central building block of every Frappe app. A single DocType definition gives you four things at once:

  • Schema: the fields and their types, stored as JSON.
  • Database table: a real SQL table generated from the schema.
  • Model and controller: a Python class (a Document subclass) with lifecycle hooks for validation and business logic.
  • UI: an auto-generated form, list view, filters and reports in the Desk.

You define the DocType once, and Frappe takes care of the table, the REST API, the form, permissions and search.

A DocType is a table

Every standard DocType maps to one SQL table named tab<DocType>. A DocType called Task lives in the table tabTask, and each field becomes a column.

SELECT name, subject, status FROM `tabTask`;

A row in that table is a document (or "doc"). In Python you work with documents, not rows:

import frappe

# Create and save a new document (a new row in tabTask)
doc = frappe.new_doc("Task")
doc.subject = "Write docs"
doc.status = "Open"
doc.insert()

# Load an existing document
doc = frappe.get_doc("Task", "TASK-0001")
print(doc.subject)

See Document API for the full set of CRUD methods.

Anatomy of a DocType

A DocType is made up of:

  • Fields: each field has a fieldtype (Data, Link, Select, Currency, Table, and more), a fieldname (the column and property name) and a label. See Fields.
  • Naming rule: how the primary key (name) is generated. See Naming.
  • Permissions: role-based rules controlling who can read/write/submit. See Permissions.
  • A controller: <doctype>.py with a Document subclass holding validation and lifecycle logic. See Controllers & Lifecycle.
  • A client script: <doctype>.js for form behaviour in the browser. See Form API.

Standard fields

Every document gets a set of standard fields automatically. You never declare them. The most important is name, the primary key.

Field Type Description
name string Primary key, unique per DocType. How you load a doc.
owner Link (User) User who created the document.
creation Datetime When it was created.
modified Datetime Last modified timestamp (used for concurrency checks).
modified_by Link (User) User who last modified it.
docstatus Int 0 Draft, 1 Submitted, 2 Cancelled. See Docstatus.
idx Int Sort/row index.

These are defined in frappe/model/__init__.py as default_fields. Child table rows also carry parent, parenttype and parentfield (see Child Tables).

Where a DocType lives

A DocType is owned by a module inside an app. Its files live on disk under that module's folder:

your_app/your_app/<module>/doctype/<doctype>/
├── <doctype>.json   # schema (fields, permissions, naming)
├── <doctype>.py     # controller (Document subclass)
├── <doctype>.js     # client script
└── test_<doctype>.py

The JSON is the source of truth; it is synced into the database table on bench migrate. See Modules & App Structure.

Special kinds of DocTypes

Most DocTypes are standard table-backed types, but a few flags change their behaviour:

  • Child table (istable): rows embedded in a parent document. See Child Tables.
  • Single (issingle): exactly one record, for settings pages. See Single DocTypes.
  • Virtual (is_virtual): no SQL table; you supply the backend. See Virtual DocTypes.
  • Submittable (is_submittable): has the Draft, Submit, Cancel flow. See Docstatus.

Next steps

Last updated 1 hour ago
Was this helpful?
Thanks!