Pagination for Task List

Number of tasks per page can be specified in the get request,
but if not specified the endpoint will return all of them.

Change-Id: I524249bf7e9f16feba8c9beaeb66267ec7da874e
This commit is contained in:
Amelia Cordwell 2017-04-26 17:12:33 +12:00 committed by Gerrit Code Review
parent 8880d0ae6b
commit 13cb4716cd
2 changed files with 41 additions and 7 deletions
README.md
stacktask/api/v1

View File

@ -41,14 +41,17 @@ Creation and management of Tasks, Tokens, and Notifications is not modular and i
Endpoints for the management of tasks, tokens, and notifications. Most of these are limited by roles, and are for admin use only.
* ../v1/task - GET
* ../v1/tasks - GET
* A json containing all tasks.
* This will be updated to take parameters to refine the list.
* ../v1/task/<uuid> - GET
* Possible parameters are:
* filters (specified below)
* tasks_per_page, defaults to 25
* page, page number to access (starts at 1)
* ../v1/tasks/<uuid> - GET
* Get details for a specific task.
* ../v1/task/<uuid> - PUT
* ../v1/tasks/<uuid> - PUT
* Update a task and retrigger pre_approve.
* ../v1/task/<uuid> - POST
* ../v1/tasks/<uuid> - POST
* approve a task
* ../v1/token - GET
* A json containing all tokens.

View File

@ -16,6 +16,7 @@ from logging import getLogger
from django.conf import settings
from django.utils import timezone
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from rest_framework.response import Response
from rest_framework.views import APIView
@ -160,15 +161,40 @@ class TaskList(APIViewWithLogger):
and their related actions.
"""
page = request.GET.get('page', 1)
tasks_per_page = request.GET.get('tasks_per_page', None)
if 'admin' in request.keystone_user['roles']:
if filters:
tasks = Task.objects.filter(**filters).order_by("-created_on")
else:
tasks = Task.objects.all().order_by("-created_on")
if tasks_per_page:
paginator = Paginator(tasks, tasks_per_page)
try:
tasks = paginator.page(page)
except EmptyPage:
return Response({'tasks': [],
'pages': paginator.num_pages,
'has_more': False,
'has_prev': False}, status=200)
# NOTE(amelia): 'has_more'and 'has_prev' names are
# based on the horizon pagination table pagination names
except PageNotAnInteger:
return Response({'error': 'Page not an integer'},
status=400)
task_list = []
for task in tasks:
task_list.append(task._to_dict())
return Response({'tasks': task_list}, status=200)
if tasks_per_page:
return Response({'tasks': task_list,
'pages': paginator.num_pages,
'has_more': tasks.has_next(),
'has_prev': tasks.has_previous()}, status=200)
else:
return Response({'tasks': task_list})
else:
if filters:
# Ignore any filters with project_id in them
@ -183,10 +209,15 @@ class TaskList(APIViewWithLogger):
tasks = Task.objects.filter(
project_id__exact=request.keystone_user['project_id']
).order_by("-created_on")
paginator = Paginator(tasks, tasks_per_page)
tasks = paginator.page(page)
task_list = []
for task in tasks:
task_list.append(task.to_dict())
return Response({'tasks': task_list}, status=200)
return Response({'tasks': task_list,
'pages': paginator.num_pages}, status=200)
class TaskDetail(APIViewWithLogger):