Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to overwrite the put() method on a python app engine model?

In Appengine, I am trying to have a property value computed automatically and stored with the object.

I have a class, Rectangle, and it has a width, height and area. Obviously the area is a function of width and height, but I want it to be a property because I want to use it for sorting. So I try to modify the put() function to sneak the area in when storing the Rectangle like so:

class Rectangle(db.Model):
    width   = db.IntegerProperty()
    height  = db.IntegerProperty()
    area    = db.IntegerProperty()

    def put(self, **kwargs):
        self.area = self.width * self.height
        super(Rectangle, self).put(**kwargs)

This works when I invoke put() on the Area object directly:

re1 = Rectangle(width=10, height=10)
re1.put()
print re1.area      # >> 10

But when I use db.put() (e.g. to save a lot of them at once), this breaks.

re2 = Rectangle(width=5, height=5)
db.put(re2)
print re2.area      # >> None

What is the proper way to 'sneak in' the computed value?

like image 385
Paul Avatar asked Sep 27 '11 12:09

Paul


1 Answers

Don't override put - as you observe, it's fragile, and doesn't get invoked if you call db.put instead of the model's put function.

Fortunately, App Engine provides a ComputedProperty which makes your use-case really easy:

class Rectangle(db.Model):
    width   = db.IntegerProperty()
    height  = db.IntegerProperty()

    @db.ComputedProperty
    def area(self):
      return self.width * self.height
like image 107
Nick Johnson Avatar answered Sep 21 '22 18:09

Nick Johnson