Filter with a Query
Part of the JSON APIs section of Coddy's Django journey. Lesson 4 of 19.
A program often wants part of the list: only the open tasks, say. APIs take such options in the query string, the part of the URL after ?. You read it with request.GET.get(), which gives None when the option is missing, so the plain URL keeps listing everything. The starter's task_list now builds its list with task_to_dict, from a QuerySet you can narrow. A bookshop filtering /api/books/?genre=poetry:
books = Book.objects.all()
genre = request.GET.get("genre")
if genre:
books = books.filter(genre=genre)A yes or no option needs more care. Everything in a URL is text, so ?done=false gives the string "false", and every non-empty string is true. if done: is true for both texts, so compare the text with "true" and with "false", each with its own filter.
Challenge
EasyIn task_list in tasks/views.py, read done from the query string and narrow the tasks before the response is built. ?done=true lists only the done tasks, ?done=false only the tasks not done, and no query still lists every task.
Press Run: the preview opens /api/tasks/?done=false and lists Buy milk and Write the report.
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()
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))
All lessons in JSON APIs
2Reading Requests
Filter with a QueryCreating with POSTPractice on your own: Django playground