From a204e78e3a24a3ede414e76f043c250d5a168031 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Fri, 4 Dec 2020 15:26:50 -0600 Subject: [PATCH] Assume composite PK when fetching instance for master view i.e. stop trying a simple get() which would assume not only a simple PK, but also assumes the PK is same as defined by the class mapper. in some cases it may be helpful to use a different PK from what mapper defines --- tailbone/views/master.py | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/tailbone/views/master.py b/tailbone/views/master.py index 8c0ee61d..62d25cea 100644 --- a/tailbone/views/master.py +++ b/tailbone/views/master.py @@ -3658,28 +3658,23 @@ class MasterView(View): doing a database lookup. If the instance cannot be found, raises 404. """ model_keys = self.get_model_key(as_tuple=True) + query = self.Session.query(self.get_model_class()) - # if just one primary key, simple get() will work - if len(model_keys) == 1: - model_key = model_keys[0] + def filtr(query, model_key): key = self.request.matchdict[model_key] + if self.key_is_integer(model_key): + key = int(key) + query = query.filter(getattr(self.model_class, model_key) == key) + return query - obj = self.Session.query(self.get_model_class()).get(key) - if not obj: - raise self.notfound() - - else: # composite key; fetch accordingly - # TODO: should perhaps use filter() instead of get() here? - query = self.Session.query(self.get_model_class()) - for i, model_key in enumerate(model_keys): - key = self.request.matchdict[model_key] - if self.key_is_integer(model_key): - key = int(key) - query = query.filter(getattr(self.model_class, model_key) == key) - try: - obj = query.one() - except orm.exc.NoResultFound: - raise self.notfound() + # filter query by composite key. we use filter() instead of a simple + # get() here in case view uses a "pseudo-PK" + for i, model_key in enumerate(model_keys): + query = filtr(query, model_key) + try: + obj = query.one() + except orm.exc.NoResultFound: + raise self.notfound() # pretend global object doesn't exist, unless access allowed if self.secure_global_objects: