Mastering Frappe Framework – Part 4: Backend Development in Frappe

Why Backend Development in Frappe Matters

Frontend determines how your app looks.

Backend determines how your app works.

In Frappe, backend development means:

  • Writing Python methods for business logic
  • Using Frappe ORM to interact with the database
  • Creating custom API endpoints
  • Running scheduled tasks
  • Sending notifications to users

1. Writing Python Methods in DocTypes

Every DocType can have a Python controller file (created when you used –create-controller).

Example: Auto-set a status when due date passes.

import frappe
from frappe.model.document import Document
from datetime import date

class ToDoPlus(Document):
    def before_save(self):
        if self.due_date and self.due_date < date.today():
            self.status = "Overdue"

Key events you can use:

  • before_insert(self) – Before a new record is saved
  • validate(self) – Data validation before saving
  • before_save(self) – Runs before save (update or insert)
  • on_update(self) – Runs after saving
  • on_trash(self) – Runs before delete

2. Using Frappe ORM for Data Operations

Instead of writing SQL, you can use Frappe ORM.

Get all pending tasks:

tasks = frappe.get_all(
    "ToDo Plus",
    filters={"status": "Pending"},
    fields=["name", "title", "due_date"]
)


Get a single document:

doc = frappe.get_doc("ToDo Plus", "TASK-0001")


Create a new record:

doc = frappe.get_doc({
    "doctype": "ToDo Plus",
    "title": "Prepare Blog Draft",
    "status": "Pending"
})
doc.insert()

3. Creating Custom API Endpoints

You can expose Python functions as REST APIs by whitelisting them.

In todo_plus/api.py:

import frappe

@frappe.whitelist()
def get_overdue_tasks():
    return frappe.get_all(
        "ToDo Plus",
        filters={"status": "Overdue"},
        fields=["name", "title", "due_date"]
    )


Access via API:

curl -X GET \
  "http://mysite.local/api/method/todo_plus.api.get_overdue_tasks" \
  -H "Authorization: token <api_key>:<api_secret>"

4. Scheduling Background Jobs

Frappe’s scheduler can run tasks automatically at intervals.

In todo_plus/tasks.py:

import frappe
from datetime import date

def mark_overdue_tasks():
    frappe.db.set_value(
        "ToDo Plus",
        {"due_date": ("<", date.today()), "status": "Pending"},
        "status",
        "Overdue"
    )


In hooks.py:

scheduler_events = {
    "daily": [
        "todo_plus.tasks.mark_overdue_tasks"
    ]
}

5. Sending Notifications

Use Frappe’s notification system to alert users.

Example:

frappe.sendmail(
    recipients=["user@example.com"],
    subject="Task Overdue",
    message="One of your tasks is overdue. Please check."
)

You can also create notifications directly from Desk → Notifications without coding.


Key Learnings from Part 4

  • How to write server-side logic with DocType controllers
  • How to use Frappe ORM for database operations
  • How to create custom API endpoints with @frappe.whitelist()
  • How to schedule jobs with Frappe’s scheduler
  • How to send email notifications programmatically

What’s Next?

In Part 5, we’ll work on Frontend Development in Frappe:

  • Custom pages with Jinja templates
  • Client scripts for interactivity
  • Modifying form layouts
  • Using REST APIs in the frontend

Leave a Reply