Refactor API collection_get to work with vue-tables-2
https://github.com/matfish2/vue-tables-2
This commit is contained in:
parent
81db564e34
commit
5c66eb5f4f
|
@ -26,6 +26,8 @@ Tailbone Web API - Master View
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import
|
from __future__ import unicode_literals, absolute_import
|
||||||
|
|
||||||
|
from rattail.config import parse_bool
|
||||||
|
|
||||||
from tailbone.api import APIView, api
|
from tailbone.api import APIView, api
|
||||||
from tailbone.db import Session
|
from tailbone.db import Session
|
||||||
|
|
||||||
|
@ -63,6 +65,52 @@ class APIMasterView(APIView):
|
||||||
return cls.collection_key
|
return cls.collection_key
|
||||||
return '{}s'.format(cls.get_object_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):
|
def _collection_get(self):
|
||||||
from sqlalchemy_filters import apply_sort, apply_pagination
|
from sqlalchemy_filters import apply_sort, apply_pagination
|
||||||
|
|
||||||
|
@ -70,33 +118,18 @@ class APIMasterView(APIView):
|
||||||
query = self.Session.query(cls)
|
query = self.Session.query(cls)
|
||||||
context = {}
|
context = {}
|
||||||
|
|
||||||
# TODO: should vuetable (etc.) be sending us valid sort_spec directly?
|
# maybe sort query
|
||||||
sort = self.request.params.get('sort')
|
sort_spec = self.make_sort_spec()
|
||||||
if sort:
|
if sort_spec:
|
||||||
# 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,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
query = apply_sort(query, sort_spec)
|
query = apply_sort(query, sort_spec)
|
||||||
|
|
||||||
# NOTE: we only paginate results if sorting is in effect, otherwise
|
# maybe paginate query
|
||||||
# record sequence is "non-determinant" (is that the word?)
|
pagination_spec = self.make_pagination_spec()
|
||||||
page = self.request.params.get('page')
|
if pagination_spec:
|
||||||
per_page = self.request.params.get('per_page')
|
number, size = pagination_spec
|
||||||
if page.isdigit() and per_page.isdigit():
|
query, pagination = apply_pagination(query, page_number=number, page_size=size)
|
||||||
page = int(page)
|
|
||||||
per_page = int(per_page)
|
|
||||||
query, pagination = apply_pagination(query, page_number=page, page_size=per_page)
|
|
||||||
|
|
||||||
# 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
|
# https://www.vuetable.com/guide/pagination.html#how-the-pagination-component-works
|
||||||
context['total'] = pagination.total_results
|
context['total'] = pagination.total_results
|
||||||
context['per_page'] = pagination.page_size
|
context['per_page'] = pagination.page_size
|
||||||
|
@ -109,8 +142,21 @@ class APIMasterView(APIView):
|
||||||
else:
|
else:
|
||||||
context['to'] = to
|
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]
|
objects = [self.normalize(obj) for obj in query]
|
||||||
|
|
||||||
|
# TODO: test this for ratbob!
|
||||||
context[self.get_collection_key()] = objects
|
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
|
return context
|
||||||
|
|
||||||
def _get(self):
|
def _get(self):
|
||||||
|
|
Loading…
Reference in a new issue