diff --git a/tailbone/views/master.py b/tailbone/views/master.py index b445bf3e..04cd30de 100644 --- a/tailbone/views/master.py +++ b/tailbone/views/master.py @@ -2475,7 +2475,10 @@ class MasterView(View): return cls.get_route_prefix() def get_row_grid_key(self): - return '{}.{}'.format(self.get_grid_key(), self.request.matchdict[self.get_model_key()]) + model_key = self.get_model_key(as_tuple=True) + key = '.'.join([self.get_grid_key()] + + [self.request.matchdict[k] for k in model_key]) + return key def get_grid_actions(self): main, more = self.get_main_actions(), self.get_more_actions() @@ -2875,10 +2878,12 @@ class MasterView(View): 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 NoResultFound: + except orm.exc.NoResultFound: raise self.notfound() # pretend global object doesn't exist, unless access allowed @@ -2889,6 +2894,18 @@ class MasterView(View): return obj + def key_is_integer(self, model_key): + + # inspect model class to determine if model_key is numeric + cls = self.get_model_class(error=False) + if cls: + attr = getattr(cls, model_key) + if isinstance(attr.type, sa.Integer): + return True + + # do not assume integer by default + return False + def get_instance_title(self, instance): """ Return a "pretty" title for the instance, to be used in the page title etc.