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)
|
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
|
Return a simple ``SortColumn`` object which denotes the field and
|
||||||
optionally, the model, to be used when sorting.
|
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):
|
def make_pagination_spec(self):
|
||||||
|
|
||||||
|
@ -153,6 +180,7 @@ class APIMasterView(APIView):
|
||||||
# maybe sort query
|
# maybe sort query
|
||||||
sort_spec = self.make_sort_spec()
|
sort_spec = self.make_sort_spec()
|
||||||
if sort_spec:
|
if sort_spec:
|
||||||
|
query = self.join_for_sort_spec(query, sort_spec)
|
||||||
query = apply_sort(query, sort_spec)
|
query = apply_sort(query, sort_spec)
|
||||||
|
|
||||||
# maybe paginate query
|
# maybe paginate query
|
||||||
|
|
|
@ -43,16 +43,20 @@ class UserView(APIMasterView):
|
||||||
def normalize(self, user):
|
def normalize(self, user):
|
||||||
return {
|
return {
|
||||||
'username': user.username,
|
'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,
|
'active': user.active,
|
||||||
}
|
}
|
||||||
|
|
||||||
def interpret_sortcol(self, order_by):
|
def interpret_sortcol(self, order_by):
|
||||||
if order_by == 'person_name':
|
if order_by == 'person_display_name':
|
||||||
return self.sortcol('display_name', 'Person')
|
return self.sortcol('Person', 'display_name')
|
||||||
|
|
||||||
return self.sortcol(order_by)
|
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')
|
@view(permission='users.list')
|
||||||
def collection_get(self):
|
def collection_get(self):
|
||||||
return self._collection_get()
|
return self._collection_get()
|
||||||
|
|
|
@ -88,17 +88,18 @@ var app = new Vue({
|
||||||
data: {
|
data: {
|
||||||
columns: [
|
columns: [
|
||||||
'username',
|
'username',
|
||||||
'person_name',
|
'person_display_name',
|
||||||
'active'
|
'active'
|
||||||
],
|
],
|
||||||
options: {
|
options: {
|
||||||
filterable: false,
|
filterable: false,
|
||||||
|
headings: {
|
||||||
|
person_display_name: "Person"
|
||||||
|
},
|
||||||
sortable: [
|
sortable: [
|
||||||
'username',
|
'username',
|
||||||
'person_name',
|
'person_display_name',
|
||||||
'active'
|
'active'
|
||||||
// TODO: add sort for Person.display_name
|
|
||||||
// 'person'
|
|
||||||
],
|
],
|
||||||
orderBy: {
|
orderBy: {
|
||||||
column: 'username',
|
column: 'username',
|
||||||
|
|
Loading…
Reference in a new issue