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
|
||||
'rattail[db,bouncer]', # 0.5.0
|
||||
'six', # 1.10.0
|
||||
'sqlalchemy-filters', # 0.8.0
|
||||
'transaction', # 1.2.0
|
||||
'waitress', # 0.8.1
|
||||
'WebHelpers2', # 2.0
|
||||
|
|
|
@ -26,7 +26,7 @@ Tailbone Web API - Master View
|
|||
|
||||
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.db import Session
|
||||
|
@ -67,26 +67,51 @@ class APIMasterView(APIView):
|
|||
|
||||
def _collection_get(self):
|
||||
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')
|
||||
if sort:
|
||||
# TODO: this is fragile, but what to do if bad params?
|
||||
sortkey, sortdir = sort.split('|')
|
||||
sortkey = getattr(cls, sortkey)
|
||||
objects = objects.order_by(getattr(sortkey, sortdir)())
|
||||
if sortdir != 'desc':
|
||||
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?)
|
||||
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)
|
||||
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]
|
||||
return {self.get_collection_key(): objects}
|
||||
# these pagination values 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
|
||||
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):
|
||||
uuid = self.request.matchdict['uuid']
|
||||
|
|
Loading…
Reference in a new issue