Add patterns for joining tables in API list methods
i.e. we needed to do an *outer* join on User.person since that can be null
This commit is contained in:
parent
93aa96a339
commit
b7319fd152
|
@ -118,12 +118,39 @@ class APIMasterView(APIView):
|
|||
"""
|
||||
return self.sortcol(order_by)
|
||||
|
||||
def sortcol(self, field_name, model_name=None):
|
||||
def sortcol(self, *args):
|
||||
"""
|
||||
Return a simple ``SortColumn`` object which denotes the field and
|
||||
optionally, the model, to be used when sorting.
|
||||
"""
|
||||
return SortColumn(field_name, model_name)
|
||||
if len(args) == 1:
|
||||
return SortColumn(args[0])
|
||||
elif len(args) == 2:
|
||||
return SortColumn(args[1], args[0])
|
||||
else:
|
||||
raise ValueError("must pass 1 arg (field_name) or 2 args (model_name, field_name)")
|
||||
|
||||
def join_for_sort_spec(self, query, sort_spec):
|
||||
"""
|
||||
This should apply any joins needed on the given query, to accommodate
|
||||
requested sorting as per ``sort_spec`` - which will be non-empty but
|
||||
otherwise no claims are made regarding its contents.
|
||||
|
||||
Please override as necessary, but in all cases you should return a
|
||||
query, either untouched or else with join(s) applied.
|
||||
"""
|
||||
model_name = sort_spec[0].get('model')
|
||||
return self.join_for_sort_model(query, model_name)
|
||||
|
||||
def join_for_sort_model(self, query, model_name):
|
||||
"""
|
||||
This should apply any joins needed on the given query, to accommodate
|
||||
requested sorting on a field associated with the given model.
|
||||
|
||||
Please override as necessary, but in all cases you should return a
|
||||
query, either untouched or else with join(s) applied.
|
||||
"""
|
||||
return query
|
||||
|
||||
def make_pagination_spec(self):
|
||||
|
||||
|
@ -153,6 +180,7 @@ class APIMasterView(APIView):
|
|||
# maybe sort query
|
||||
sort_spec = self.make_sort_spec()
|
||||
if sort_spec:
|
||||
query = self.join_for_sort_spec(query, sort_spec)
|
||||
query = apply_sort(query, sort_spec)
|
||||
|
||||
# maybe paginate query
|
||||
|
|
|
@ -43,16 +43,20 @@ class UserView(APIMasterView):
|
|||
def normalize(self, user):
|
||||
return {
|
||||
'username': user.username,
|
||||
'person_name': six.text_type(user.person or ''),
|
||||
'person_display_name': (user.person.display_name or '') if user.person else '',
|
||||
'active': user.active,
|
||||
}
|
||||
|
||||
def interpret_sortcol(self, order_by):
|
||||
if order_by == 'person_name':
|
||||
return self.sortcol('display_name', 'Person')
|
||||
|
||||
if order_by == 'person_display_name':
|
||||
return self.sortcol('Person', 'display_name')
|
||||
return self.sortcol(order_by)
|
||||
|
||||
def join_for_sort_model(self, query, model_name):
|
||||
if model_name == 'Person':
|
||||
query = query.outerjoin(model.Person)
|
||||
return query
|
||||
|
||||
@view(permission='users.list')
|
||||
def collection_get(self):
|
||||
return self._collection_get()
|
||||
|
|
|
@ -88,17 +88,18 @@ var app = new Vue({
|
|||
data: {
|
||||
columns: [
|
||||
'username',
|
||||
'person_name',
|
||||
'person_display_name',
|
||||
'active'
|
||||
],
|
||||
options: {
|
||||
filterable: false,
|
||||
headings: {
|
||||
person_display_name: "Person"
|
||||
},
|
||||
sortable: [
|
||||
'username',
|
||||
'person_name',
|
||||
'person_display_name',
|
||||
'active'
|
||||
// TODO: add sort for Person.display_name
|
||||
// 'person'
|
||||
],
|
||||
orderBy: {
|
||||
column: 'username',
|
||||
|
|
Loading…
Reference in a new issue