How to build a simple API service¶
This example demonstrates how to build a simple CRUD (Create, Read, Update, Delete) API using nanodjango’s built-in Django Ninja support.
Lets implement a simple “Todo” app with a database model and endpoints for creating, listing, retrieving, updating, and deleting items.
Example code¶
from django.db import models
from nanodjango import Django
app = Django()
# Standard Django model
# Decorator registers it with the admin site
@app.admin
class Todo(models.Model):
title = models.CharField(max_length=200)
done = models.BooleanField(default=False)
def __str__(self):
return self.title
# Generate API schemas from the models
# One which has all fields for reading...
class TodoSchema(app.ninja.ModelSchema):
class Meta:
model = Todo
fields = "__all__"
# ... and one which doesn't have the ID, for create and update payloads - we'll
# be getting the ID from the URL
class TodoIn(app.ninja.ModelSchema):
class Meta:
model = Todo
exclude = ["id"]
# CRUD views, registered under the app's API - they all get the URL prefix /api
@app.api.post("/todos", response=TodoSchema)
def create_todo(request, payload: TodoIn):
return Todo.objects.create(**payload.dict())
@app.api.get("/todos", response=list[TodoSchema])
def list_todos(request):
return Todo.objects.all()
@app.api.get("/todos/{todo_id}", response=TodoSchema)
def get_todo(request, todo_id: int):
try:
return Todo.objects.get(id=todo_id)
except Todo.DoesNotExist:
return {"error": "Todo not found"}, 404
@app.api.put("/todos/{todo_id}", response=TodoSchema)
def update_todo(request, todo_id: int, payload: TodoIn):
try:
todo = Todo.objects.get(id=todo_id)
except Todo.DoesNotExist:
return {"error": "Todo not found"}, 404
for key, value in payload.dict().items():
setattr(todo, key, value)
todo.save()
return todo
@app.api.delete("/todos/{todo_id}")
def delete_todo(request, todo_id: int):
try:
todo = Todo.objects.get(id=todo_id)
except Todo.DoesNotExist:
return {"error": "Todo not found"}, 404
todo.delete()
return {"message": "Deleted"}
Running the app¶
Run the API using :
cd /examples
uvx nanodjango run hello_api.py
Endpoints¶
All endpoints are available under /api/:
1. Create a Todo (POST)
URL:
/api/todosBody: JSON object with
titleand optionaldone
curl -X POST http://127.0.0.1:8000/api/todos \
-H "Content-Type: application/json" \
-d '{"title": "Learn nanodjango", "done": false}'
Response:
{"id": 1, "title": "Learn nanodjango", "done": false}
2. List all Todos (GET)
URL:
/api/todos
curl http://127.0.0.1:8000/api/todos
Response:
[{"id": 1, "title": "Learn nanodjango", "done": false}]
3. Get a Todo by ID (GET)
URL:
/api/todos/{id}
curl http://127.0.0.1:8000/api/todos/1
Response:
{"id": 1, "title": "Learn nanodjango", "done": false}
4. Update a Todo (PUT)
URL:
/api/todos/{id}Body: JSON object with new
donestate
curl -X PUT http://127.0.0.1:8000/api/todos/1 \
-H "Content-Type: application/json" \
-d '{"done": true}'
Response:
{"id": 1, "title": "Learn nanodjango", "done": true}
5. Delete a Todo (DELETE)
URL:
/api/todos/{id}
curl -X DELETE http://127.0.0.1:8000/api/todos/1
Response:
{"message": "Deleted"}