TODO App Example
A simple TODO application built with Framework M.
DocType: Task
# apps/todo/src/doctypes/task/doctype.py
from __future__ import annotations
from datetime import date
from typing import ClassVar
from framework_m import DocType, Field
class Task(DocType):
"""A simple task/todo item."""
__doctype_name__: ClassVar[str] = "Task"
# Core fields
title: str = Field(description="Task title")
description: str = Field(default="", description="Task description")
# Status
status: str = Field(
default="Open",
description="Current status",
)
priority: str = Field(
default="Medium",
description="Priority level",
)
# Dates
due_date: date | None = Field(default=None, description="Due date")
completed_date: date | None = Field(default=None, description="Completed date")
class Meta:
naming_rule: ClassVar[str] = "autoincrement"
api_resource: ClassVar[bool] = True
Controller: TaskController
# apps/todo/src/doctypes/task/controller.py
from __future__ import annotations
from datetime import date
from framework_m import Controller
from .doctype import Task
class TaskController(Controller[Task]):
"""Business logic for Task."""
async def validate(self, context=None):
"""Validate task before save."""
if not self.doc.title.strip():
raise ValueError("Title is required")
async def before_save(self, context=None):
"""Auto-set completed date when status changes to Done."""
if self.doc.status == "Done" and not self.doc.completed_date:
self.doc.completed_date = date.today()
API Usage
# List all tasks
curl http://localhost:8000/api/v1/resource/Task
# Create a task
curl -X POST http://localhost:8000/api/v1/resource/Task \
-H "Content-Type: application/json" \
-d '{
"title": "Buy groceries",
"priority": "High",
"due_date": "2024-01-15"
}'
# Update task status
curl -X PUT http://localhost:8000/api/v1/resource/Task/1 \
-H "Content-Type: application/json" \
-d '{"status": "Done"}'
# Filter by status
curl "http://localhost:8000/api/v1/resource/Task?filters=[{\"field\":\"status\",\"operator\":\"eq\",\"value\":\"Open\"}]"
Quick Start
# Create the app
uv run m new:app todo
# Create the Task doctype
cd todo
uv run m new:doctype Task
# Edit doctype.py and controller.py as shown above
# Run migration
uv run m migrate init
uv run m migrate create "Add Task doctype" --autogenerate
uv run m migrate
# Start Studio
uv run m studio