- Controller Methods
- Controller Hooks
Actions and Links
A DocType is the core building block of any application based on the Frappe Framework. It describes the Model and the View of your data. It contains what fields are stored for your data, and how they behave with respect to each other. It contains information about how your data is named. It also enables rich Object Relational Mapper (ORM) pattern which we will discuss later in this guide. When you create a DocType, a JSON object is created which in turn creates a database table.
ORM is just an easy way to read, write and update data in a database without writing explicit SQL statements.
To enable rapid application development, Frappe Framework follows some standard conventions.
DocType is always singular. If you want to store a list of articles in the database, you should name the doctype Article.
Table names are prefixed with tab. So the table name for Article doctype is tabArticle.
The standard way to create a DocType is by typing new doctype in the search bar in the Desk.
A DocType not only stores fields, but also other information about how your data behaves in the system. We call this Meta. Since this meta-data is also stored in a database table, it makes it easy to change meta-data on the fly without writing much code. Learn more about Meta.
A DocType is also a DocType. This means that we store meta-data as the part of the data.
After creating a DocType, Frappe can provide many features out-of-the-box. If you go to /desk#List/ToDo you will be routed to the List View in the desk.
Similarly, you get a Form View at the route /desk#Form/ToDo/000001. The Form is used to create new docs and view them.
A DocType will always belong to a module, to enable easier grouping of related models. Frappe comes with a lot of built-in modules. For e.g
Core - contains doctypes like DocType, DocField, Report, System Settings, etc
Desk - contains doctypes like ToDo, Event, Note, Kanban Board, etc
Email - contains doctypes like Email Account, Newsletter, Email Group, etc
Modules also helps in grouping of code files in directories. The controller files generated by a DocType will live in it's respective Module directory.
A DocField is a list of fields which describes what properties a DocType will have. For instance, a ToDo doctype has fields description, status and priority. These ultimately become columns in the database table tabToDo.
The DocField stores meta-data about the field. Some of them are described below.
Similar to the depends_on property which determines whether a field will be displayed or not, in Version 12 we have introduced two new properties:
mandatory_depends_on: If this condition is satisfied, the field will be mandatory.
read_only_depends_on: If this condition is satisfied, the field will be read only.
Frappe comes with more than 30 different fieldtypes out-of-the-box. These fieldtypes serve a variety of use-cases. Learn more about Field Types.
All docs in Frappe have a primary key called name. This is the unique id by which you will be finding records and manipulating them using the ORM. You can configure how docs should be named when a new document is created. The following are the ways you can setup naming in a DocType.
You can set the name by the autoname property of the DocType.
The doc name is fetched from the value of the field provided.
You can provide a naming pattern which will be incremented automatically. For e.g, if you set it as PRE.#####, the first document created will have the name as PRE00001, and second one will be PRE00002 and so on.
The naming pattern is derived from a field in the document. For e.g, you have a field naming_series in your document and it's value is set as PRE.#####, then that will be the pattern used for generating the name. This value can change per document. So the next document can have a different pattern.
This works only if you have a field called naming_series in your DocType.
If you set it as Prompt, the name is required to be filled in manually.
This is the most flexible one when it comes to configuring your naming schemes.
Let's say we have
Everything outside the curly braces are plain text. Keywords inside the curly braces will be evaluated based on what they represent. In this case:
MM: will be replaced by the current month
fieldname1: will be replaced by the value of fieldname1 in the document
#####: will generate a series, which starts with 00001
So the final name may look like, EXAMPLE-02-test-value1-value2-00001
By Controller Method
You can also define a name programatically by declaring an autoname method in the controller class. Example
By Document Naming Rule
You can also create rules for naming DocTypes by creating Document Naming Rule
You can create multiple Document Naming Rules for a particular doctype that can be applied selectively based on filters.
To define a Document Naming Rule you have to specify
Document Type it is being applied on
Priority of the rule (rules with higher priority will be applied first)
Conditions to apply the rule
You can define various numbering prefixes for the rule based on the conditions defined. This is done by setting a prefix and the number of digits for that rule.
For example if you are creating a separate numbering for high priority todos:
Will lead to numbering like todo-high-001, todo-high-002 and so on.
Priority of Naming
Naming priority is as follows
Document Naming Rule
autoname controller method.
autoname DocType property
Child DocTypes do not follow naming rules
Amended documents have a suffix (-1, -2 etc) to the original document
A Document is an instance of a DocType. It usually maps to a single row in the database table. We refer to it as doc in code.
Let's say we have a DocType ToDo with the following fields:
Now, if we want to query a document from the database, we can use the ORM.
You get the values of description, status and priority, but you also get fields like creation, owner and modified_by which are fields added by default by the framework on all++docs++.
A Controller is a normal python class which extends from frappe.model.Document base class. This base class is the core logic of a DocType. It handles how values are loaded from the database, how they are parsed and saved back to the database.
When you create a DocType named Person, a python file is created by the name person.py and the contents look like:
All the fields are available to the class as attributes.
You can add custom methods to your Controller and it will be callable using the doc object. For example,
You can also override the pre-defined document methods to add your own behaviour. For e.g to override the save() method,
To add custom behaviour during the lifecycle of a document, we have controller hooks.
To use a controller hook, just define a class method with that name. For e.g
1. Create a document
To create a new document and save it to the database,
2. Load a document
To get an existing document from the database,
Up until now we have only seen DocTypes that can have a single value for each field. However, there might be a need for storing multiple records against one record, also known as many-to-one relationships. A Child DocType is doctype which can only be linked to a parent DocType. To make a Child DocType make sure to check Is Child Table while creating the doctype.
Child DocType records are directly attached to the parent doc.
A Single DocType is a DocType that holds only one record in the database. It is useful for persisting things like System Settings, which don't make sense to have multiple records.
Single DocTypes are stored in the tabSingles table in the database, with each property having its own record.
Actions and Links
A DocType may also have Daily Action that will result in a button creation on the DocType View. Supported actions are:
Server Action: This will trigger a whitelisted server action.
A standard navigation aid to the DocType view is the Links section on the dashboard. This helps the viewer identify at a glance which document types are connected to this DocType and can quickly create new related documents.
Configuration of Actions and Links
If you are using the same application for multiple site (tenants), each site may want specific customization on top of the DocType. For example if you have a "Customer" DocType each user may want addition Custom Fields or naming or other configuration that would be specific to them.
To allow for site-specific customization, Frappe Framework has multiple approaches:
Custom Field: A DocType that keeps track of site-specific fields.
Property Setter: This keeps track of specific properties that are overridden in DocType and its children.
Customize Form: A view that helps you easily customize DocTypes
Client Script: Additional client-side event handlers.
Server Script: Additional server-side business logic.
Custom DocPerm: Additional Permission (handled via Role Permission Manager)
Customize Form is a view that helps you override properties of a DocType and add Custom Fields via a single view.
When you change any properties of the DocType via Customize Form, it will not change the underlying DocType but add new custom objects to override those properties. This is done in a seamless manner.
Adding Custom Links and Actions
You can also add / edit Links and Actions via Customize Form. These changes are saved in the same DocTypes (DocType Link and DocType Action) but with a custom property checked.
These addtional (custom) configurations are automatically applied when metadata is fetched via frappe.get_meta.
Updated on: 01/04/2023