Frappe v15 DocField
Complete & Accurate Developer Documentation**
A DocField in Frappe defines the structure, behavior, and properties of an individual field inside a DocType. Each field in a form—such as Text, Table, Link, Check—is represented as a DocField object. Understanding DocFields is essential for building stable, scalable, and maintainable ERPNext/Frappe applications.
This guide explains every important aspect of DocFields in Frappe v15 with technical accuracy and real-world examples.
What Is a DocField in Frappe?
A DocField is a metadata object that defines:
- The type of field (e.g., Data, Date, Link, Table)
- How the field behaves (e.g., mandatory, read-only, hidden)
- Field options (e.g., link target DocType, default value)
- UI properties (label, placeholder, description)
- Database column mapping
- Permissions and display logic
- Dependencies & triggers
Each DocField is stored inside the DocType JSON/DB structure and is loaded automatically when rendering forms, building APIs, and saving documents.
Where Are DocFields Stored in Frappe v15?
DocFields are stored inside a DocType as a list:
- doctype.json (in module folder)
- tabDocField (database)
- frappe.model.meta cache system
Example folder path:
/apps/my_app/my_app/my_module/doctype/mydoctype/mydoctype.json
Inside the JSON:
{
"fieldname": "customer_name",
"fieldtype": "Data",
"label": "Customer Name",
"reqd": 1,
"unique": 1,
"in_list_view": 1
}
Core DocField Properties
These are the most critical DocField attributes in Frappe v15.
Basic Properties
| Property | Description |
| label | Display name shown in the UI |
| fieldname | Internal identifier used in code & DB |
| fieldtype | Type of field (Data, Select, Link, Table, etc.) |
| reqd | Marks field as mandatory |
| default | Default value |
| options | Additional configuration depending on fieldtype |
| description | Helper text shown below the field |
| placeholder | Placeholder text inside input box |
Database Properties
| Property | Description |
| unique | Makes field unique across the DocType |
| search_index | Adds search index for faster lookup |
| bold | Highlights value visually |
| no_copy | Restricts value copying on duplication |
Permission & Visibility Properties
| Property | Behavior |
| read_only | Prevents editing the field |
| hidden | Removes field from UI |
| set_only_once | Value editable only during creation |
| in_list_view | Shows field in list view |
| in_standard_filter | Allows filtering by field |
| in_filter | Adds field to sidebar filter panel |
UI Behavior Properties
| Property | Description |
| depends_on | Conditionally shows field |
| mandatory_depends_on | Conditionally sets field mandatory |
| read_only_depends_on | Conditionally sets field read-only |
| collapsible | Makes a section collapsible |
| collapsible_depends_on | Auto-collapse based on value |
Example condition:
eval:doc.status === "Closed"
Fieldtype-Specific Behavior
Different DocField fieldtypes use options differently.
1. Link Field
"fieldtype": "Link",
"options": "Customer"
Links to the “Customer” DocType.
2. Select Field
“options”: “High\nMedium\nLow”
3. Table Field
"fieldtype": "Table",
"options": "Sales Invoice Item"
Represents a child table linked to a Child DocType.
4. Dynamic Link
"fieldtype": "Dynamic Link",
"options": "reference_doctype"
Value of reference_doctype determines target link.
5. Attach Field
"fieldtype": "Attach"
Stores file URL via File DocType.
6. Formula Field
"fieldtype": "Float",
"formula": "qty * rate"
Auto-calculates field value.
Setting Conditional Logic in DocFields
Frappe supports UI scripting inside metadata using the depends_on engine.
Examples:
Show when checkbox is ticked
depends_on: eval:doc.is_active == 1
Make field mandatory based on condition
mandatory_depends_on: eval:doc.amount > 0
Read-only when submitted
read_only_depends_on: eval:doc.docstatus == 1
DocField Lifecycle in Frappe v15
- Loaded from DocType metadata
- Rendered in UI (Desk Form/Quick Entry/List)
- Validated via fieldtype rules
- Assigned default values
- Affected by Form Scripts (JS)
- Saved to DB with appropriate datatype
- Processed by hooks and workflows
DocField in Python (Meta Usage)
Access DocField via Meta:
meta = frappe.get_meta("Sales Invoice")
fields = meta.get("fields")
for df in fields:
print(df.fieldname, df.fieldtype)
DocField in Client Script
Access field properties:
frappe.ui.form.on("Sales Invoice", {
refresh(frm) {
frm.set_df_property("due_date", "read_only", 1);
}
});
Best Practices for DocFields (v15 Recommended)
- Use lowercase_fieldnames with underscores
- Avoid spaces or special characters in fieldname
- Use Link instead of Data where relational data exists
- Prefer Table fields for structured child data
- Avoid using too many custom scripts when DocField logic suffices
- Use collapsible sections for long forms
- Always set mandatory fields carefully to avoid workflow issues
- Keep naming consistent across modules
Troubleshooting DocField Issues
Field not visible in form
Check:
- hidden != 1
- depends_on logic
- Role permissions
- Custom Form overrides
Field not saving value
Ensure:
- Fieldtype supports input
- Fieldname is valid
- DB column exists
- No custom script resetting it
Child table not loading
Confirm:
- Child DocType istable = 1
- Table field options references correct DocType
Duplicate fieldname error
Fix by:
- Renaming field
- Checking merge conflicts
- Ensuring custom fields don’t overlap
Cross-References for goerpnext.com Docs
- DocType Basics
- Fieldtypes Guide
- Virtual DocFields
- Naming in Frappe
- Customize Form
- Meta Class API
Conclusion
DocFields are the core building blocks of every DocType in Frappe v15. Understanding their properties, behavior, and configuration is essential for customizing ERPNext, creating new applications, designing workflows, and ensuring data consistency.
This guide ensures you can confidently configure fields, implement conditional logic, and enhance user experience throughout your ERPNext platform.