Creating with POST
Part of the JSON APIs section of Coddy's Django journey. Lesson 5 of 19.
Programs can read your tasks but not add one. To create, a program sends a POST to the list's URL with the task as JSON in the request's body, the data that travels with it. A form fills request.POST; JSON does not. Read the raw body, request.body, and turn it into Python with json.loads.
One URL can do two jobs, picked by request.method. This view only echoes what it was sent:
def echo(request):
if request.method == "POST":
data = json.loads(request.body)
return JsonResponse({"you_sent": data})
return JsonResponse({"hint": "Send me a POST"})A view that creates something answers 201 Created with the new object, so the program learns its id. A key the program may leave out is read with a default: data.get("colour", "black").
Challenge
MediumLet programs create tasks with POST /api/tasks/:
- Read the JSON body, like
{"title": "Pay rent", "priority": "high"}, and create the task. Withoutpriorityit gets"normal". - Answer with the new task and status
201. - GET keeps listing and filtering.
The address bar only sends GET. Press Run, then type this in the Shell tab: from django.test import Client; print(Client().post("/api/tasks/", {"title": "Pay rent"}, content_type="application/json").json())
Try it yourself
from django.http import JsonResponse
from django.shortcuts import render
from .models import Task
def task_to_dict(task):
return {
"id": task.id,
"title": task.title,
"done": task.done,
"priority": task.priority,
}
def home(request):
return render(request, "tasks/home.html", {"tasks": Task.objects.all()})
def stats(request):
data = {
"total": Task.objects.count(),
"done": Task.objects.filter(done=True).count(),
}
return JsonResponse(data)
def task_list(request):
tasks = Task.objects.all()
done = request.GET.get("done")
if done == "true":
tasks = tasks.filter(done=True)
elif done == "false":
tasks = tasks.filter(done=False)
return JsonResponse([task_to_dict(task) for task in tasks], safe=False)
def task_detail(request, pk):
task = Task.objects.filter(pk=pk).first()
if task is None:
return JsonResponse({"error": "Task not found"}, status=404)
return JsonResponse(task_to_dict(task))
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in JSON APIs
2Reading Requests
Filter with a QueryCreating with POSTPractice on your own: Django playground