Refactor API collection_get to work with vue-tables-2

https://github.com/matfish2/vue-tables-2
This commit is contained in:
Lance Edgar 2018-11-20 20:49:13 -06:00
parent 81db564e34
commit 5c66eb5f4f

View file

@ -26,6 +26,8 @@ Tailbone Web API - Master View
from __future__ import unicode_literals, absolute_import
from rattail.config import parse_bool
from tailbone.api import APIView, api
from tailbone.db import Session
@ -63,6 +65,52 @@ class APIMasterView(APIView):
return cls.collection_key
return '{}s'.format(cls.get_object_key())
def make_sort_spec(self):
# these params are based on 'vuetable-2'
# https://www.vuetable.com/guide/sorting.html#initial-sorting-order
if 'sort' in self.request.params:
sort = self.request.params['sort']
sortkey, sortdir = sort.split('|')
if sortdir != 'desc':
sortdir = 'asc'
return [
{
# 'model': self.model_class.__name__,
'field': sortkey,
'direction': sortdir,
},
]
# these params are based on 'vue-tables-2'
# https://github.com/matfish2/vue-tables-2#server-side
if 'orderBy' in self.request.params and 'ascending' in self.request.params:
return [
{
# 'model': self.model_class.__name__,
'field': self.request.params['orderBy'],
'direction': 'asc' if parse_bool(self.request.params['ascending']) else 'desc',
},
]
def make_pagination_spec(self):
# these params are based on 'vuetable-2'
# https://github.com/ratiw/vuetable-2-tutorial/wiki/prerequisite#sample-api-endpoint
if 'page' in self.request.params and 'per_page' in self.request.params:
page = self.request.params['page']
per_page = self.request.params['per_page']
if page.isdigit() and per_page.isdigit():
return int(page), int(per_page)
# these params are based on 'vue-tables-2'
# https://github.com/matfish2/vue-tables-2#server-side
if 'page' in self.request.params and 'limit' in self.request.params:
page = self.request.params['page']
limit = self.request.params['limit']
if page.isdigit() and limit.isdigit():
return int(page), int(limit)
def _collection_get(self):
from sqlalchemy_filters import apply_sort, apply_pagination
@ -70,33 +118,18 @@ class APIMasterView(APIView):
query = self.Session.query(cls)
context = {}
# TODO: should vuetable (etc.) be sending us valid sort_spec directly?
sort = self.request.params.get('sort')
if sort:
# TODO: this is fragile, but what to do if bad params?
sortkey, sortdir = sort.split('|')
if sortdir != 'desc':
sortdir = 'asc'
sort_spec = [
{
# 'model': self.model_class.__name__,
'field': sortkey,
'direction': sortdir,
},
]
# maybe sort query
sort_spec = self.make_sort_spec()
if sort_spec:
query = apply_sort(query, sort_spec)
# NOTE: we only paginate results if sorting is in effect, otherwise
# record sequence is "non-determinant" (is that the word?)
page = self.request.params.get('page')
per_page = self.request.params.get('per_page')
if page.isdigit() and per_page.isdigit():
page = int(page)
per_page = int(per_page)
query, pagination = apply_pagination(query, page_number=page, page_size=per_page)
# maybe paginate query
pagination_spec = self.make_pagination_spec()
if pagination_spec:
number, size = pagination_spec
query, pagination = apply_pagination(query, page_number=number, page_size=size)
# these pagination values are based on 'vuetable-2'
# these properties are based on 'vuetable-2'
# https://www.vuetable.com/guide/pagination.html#how-the-pagination-component-works
context['total'] = pagination.total_results
context['per_page'] = pagination.page_size
@ -109,8 +142,21 @@ class APIMasterView(APIView):
else:
context['to'] = to
# these properties are based on 'vue-tables-2'
# https://github.com/matfish2/vue-tables-2#server-side
context['count'] = pagination.total_results
objects = [self.normalize(obj) for obj in query]
# TODO: test this for ratbob!
context[self.get_collection_key()] = objects
# these properties are based on 'vue-tables-2'
# https://github.com/matfish2/vue-tables-2#server-side
context['data'] = objects
if 'count' not in context:
context['count'] = len(objects)
return context
def _get(self):