Use sqlalchemy-filters package for REST API collection_get
just sorting and pagination so far though, no actual filters yet
This commit is contained in:
parent
3e8d6a27f1
commit
46501b7caa
1
setup.py
1
setup.py
|
@ -88,6 +88,7 @@ requires = [
|
||||||
'pyramid_tm', # 0.3
|
'pyramid_tm', # 0.3
|
||||||
'rattail[db,bouncer]', # 0.5.0
|
'rattail[db,bouncer]', # 0.5.0
|
||||||
'six', # 1.10.0
|
'six', # 1.10.0
|
||||||
|
'sqlalchemy-filters', # 0.8.0
|
||||||
'transaction', # 1.2.0
|
'transaction', # 1.2.0
|
||||||
'waitress', # 0.8.1
|
'waitress', # 0.8.1
|
||||||
'WebHelpers2', # 2.0
|
'WebHelpers2', # 2.0
|
||||||
|
|
|
@ -26,7 +26,7 @@ Tailbone Web API - Master View
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import
|
from __future__ import unicode_literals, absolute_import
|
||||||
|
|
||||||
from paginate_sqlalchemy import SqlalchemyOrmPage
|
from sqlalchemy_filters import apply_sort, apply_pagination
|
||||||
|
|
||||||
from tailbone.api import APIView, api
|
from tailbone.api import APIView, api
|
||||||
from tailbone.db import Session
|
from tailbone.db import Session
|
||||||
|
@ -67,26 +67,51 @@ class APIMasterView(APIView):
|
||||||
|
|
||||||
def _collection_get(self):
|
def _collection_get(self):
|
||||||
cls = self.get_model_class()
|
cls = self.get_model_class()
|
||||||
objects = self.Session.query(cls)
|
query = self.Session.query(cls)
|
||||||
|
context = {}
|
||||||
|
|
||||||
|
# TODO: should vuetable (etc.) be sending us valid sort_spec directly?
|
||||||
sort = self.request.params.get('sort')
|
sort = self.request.params.get('sort')
|
||||||
if sort:
|
if sort:
|
||||||
# TODO: this is fragile, but what to do if bad params?
|
# TODO: this is fragile, but what to do if bad params?
|
||||||
sortkey, sortdir = sort.split('|')
|
sortkey, sortdir = sort.split('|')
|
||||||
sortkey = getattr(cls, sortkey)
|
if sortdir != 'desc':
|
||||||
objects = objects.order_by(getattr(sortkey, sortdir)())
|
sortdir = 'asc'
|
||||||
|
|
||||||
# NOTE: we only page results if sorting is in effect, otherwise
|
sort_spec = [
|
||||||
|
{
|
||||||
|
# 'model': self.model_class.__name__,
|
||||||
|
'field': sortkey,
|
||||||
|
'direction': sortdir,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
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?)
|
# record sequence is "non-determinant" (is that the word?)
|
||||||
page = self.request.params.get('page')
|
page = self.request.params.get('page')
|
||||||
per_page = self.request.params.get('per_page')
|
per_page = self.request.params.get('per_page')
|
||||||
if page.isdigit() and per_page.isdigit():
|
if page.isdigit() and per_page.isdigit():
|
||||||
page = int(page)
|
page = int(page)
|
||||||
per_page = int(per_page)
|
per_page = int(per_page)
|
||||||
objects = SqlalchemyOrmPage(objects, items_per_page=per_page, page=page)
|
query, pagination = apply_pagination(query, page_number=page, page_size=per_page)
|
||||||
|
|
||||||
objects = [self.normalize(obj) for obj in objects]
|
# these pagination values are based on 'vuetable-2'
|
||||||
return {self.get_collection_key(): objects}
|
# https://www.vuetable.com/guide/pagination.html#how-the-pagination-component-works
|
||||||
|
context['total'] = pagination.total_results
|
||||||
|
context['per_page'] = pagination.page_size
|
||||||
|
context['current_page'] = pagination.page_number
|
||||||
|
context['last_page'] = pagination.num_pages
|
||||||
|
context['from'] = pagination.page_size * (pagination.page_number - 1) + 1
|
||||||
|
to = pagination.page_size * (pagination.page_number - 1) + pagination.page_size
|
||||||
|
if to > pagination.total_results:
|
||||||
|
context['to'] = pagination.total_results
|
||||||
|
else:
|
||||||
|
context['to'] = to
|
||||||
|
|
||||||
|
objects = [self.normalize(obj) for obj in query]
|
||||||
|
context[self.get_collection_key()] = objects
|
||||||
|
return context
|
||||||
|
|
||||||
def _get(self):
|
def _get(self):
|
||||||
uuid = self.request.matchdict['uuid']
|
uuid = self.request.matchdict['uuid']
|
||||||
|
|
Loading…
Reference in a new issue