I need to update some properties of an NDB model transactionally, and it seems sensible to make the update function a classmethod:
class Thing(ndb.Model):
cost=ndb.IntegerProperty()
@classmethod
@ndb.transactional()
def add_cost(cls, thid, amount):
thing=cls.get_by_id(thid)
thing.cost+=amount
return thing
This is used thus:
# Add 25 to cost
thing=Thing.add_cost(thing.key.id(), 25)
Does it matter which order the decorators appear?
Yes, the order of decorators does matter. From the PEP 318 -- Decorators for Functions and Methods:
In your case it would translate to:
A decorator would wrap the function it is decorating. Here, your
add_cost
function is wrapped byndb.transactional
so everything thing within the function happens in the context of a transaction and then the method returned by that is wrapped byclassmethod
which returns a descriptor object.So, when you apply multiple decorators in a class, then decorators such as
classmethod
orstaticmethod
should be the top ones. If you change the order you would receive anTypeError: unbound method ....
type of error if the other decorator doesn't accept descriptors.You can also refer to following post for more details:
Why can @decorator not decorate a staticmethod or a classmethod?