Open ssirowy opened 6 years ago
It is possible to define two view classes, one without the query method and one with the query method. The class without the query method would then serve /computers
, and the class with the query (which may inherit from the one without the query) would serve /persons/:id/computers
. The query method then also does not have to check whether the id
is passed, because it always is. This would look like:
class ComputerList(ResourceList):
schema = ComputerSchema
data_layer = {'session': db.session, 'model': Computer}
class PersonComputerList(ComputerList)
def query(self, view_kwargs):
try:
self.session.query(Person).filter_by(id=view_kwargs['id']).one()
except NoResultFound:
raise ObjectNotFound({'parameter': 'id'}, "Person: {} not found".format(view_kwargs['id']))
else:
return self.session.query(Computer).join(Person).filter(Person.id == view_kwargs['id'])
def before_create_object(self, data, view_kwargs):
person = self.session.query(Person).filter_by(id=view_kwargs['id']).one()
data['person_id'] = person.id
view_kwargs = True
data_layer = {'session': db.session,
'model': Computer,
'methods': {'query': query,
'before_create_object': before_create_object}}
...
api.route(ComputerList, 'computer_list', '/computers')
api.route(PersonComputerList, 'person_computer_list', '/persons/<int:id>/computers')
I think this provides a nicer separation of concerns, and keeps things more flexible e.g. in the case described in question 2.
Note the view_kwargs = True
class attribute on PersonComputerList
which is necessary to prevent Werkzeug router errors (although I wasted some time reading over it, it is in fact documented).
Not sure where to post a question regarding best practices of this library, so I thought I'd include an issue.
In the First example docs, the SQL alchemy models specify a Person, the computers and the relationships between them. So far, so good.
At the end the example, there are two APIS for getting lists of computers. One is the whole list, the other is a given person's computers:
The
/computers
route seems to work as I'd expect, but the latter one does not. It appears you are overridingquery
in the example, which the docs don't really go into detail about, and it doesn't seem to make use thebefore_get
call.Without thinking about how the library works, it seems like it'd be great if I had a hook somewhere to return the value of:
and just return the computers object off of my SQLAlchemy model since that was already set up.
Several questions then:
ComputerList
object to branch based off theview_kwargs
to decide how to filter the list?before_get_object
(and other variants)? In a typical setup, what is it intended to manipulate before the rest of the method runs?