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 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):
|
||||
|
|
Loading…
Reference in a new issue