Using Property Builtin with GAE Datastore's Model
Question: I want to make attributes of GAE Model properties. The reason is for cases
like to turn the value into uppercase before storing it. For a plain Python
class, I would do something like:

    
    
    Foo(db.Model):
        def get_attr(self):
           return self.something
        def set_attr(self, value):
           self.something = value.upper() if value != None else None
        attr = property(get_attr, set_attr)
    

However, GAE Datastore have their own concept of Property class, I looked into
the
[documentation](http://code.google.com/appengine/docs/python/datastore/propertyclass.html#Property)
and it seems that I could override `get_value_for_datastore(model_instance)`
to achieve my goal. Nevertheless, I don't know what `model_instance` is and
how to extract the corresponding field from it.

Is overriding GAE Property classes the right way to provides getter/setter-
like functionality? If so, how to do it?

**Added:**

One potential issue of overriding `get_value_for_datastore` that I think of is
it might not get called before the object was put into datastore. Hence
getting the attribute before storing the object would yield an incorrect
value.


Answer: Subclassing GAE's
[Property](http://code.google.com/appengine/docs/python/datastore/propertyclass.html)
class is especially helpful if you want more than one "field" with similar
behavior, in one or more models. Don't worry, `get_value_for_datastore` and
`make_value_from_datastore` **are** going to get called, on any store and
fetch respectively -- so if you need to do anything fancy (including but not
limited to uppercasing a string, which isn't actually all _that_ fancy;-),
overriding these methods in your subclass is just fine.

**Edit** : let's see some example code (net of imports and `main`):

    
    
    class MyStringProperty(db.StringProperty):
        def get_value_for_datastore(self, model_instance):
            vv = db.StringProperty.get_value_for_datastore(self, model_instance)
            return vv.upper()
    
    class MyModel(db.Model):
        foo = MyStringProperty()
    
    class MainHandler(webapp.RequestHandler):
    
        def get(self):
            my = MyModel(foo='Hello World')
            k = my.put()
            mm = MyModel.get(k)
            s = mm.foo
            self.response.out.write('The secret word is: %r' % s)
    

This shows you the string's been uppercased in the datastore -- but if you
change the `get` call to a simple `mm = my` you'll see the _in-memory_
instance wasn't affected.

But, a `db.Property` instance itself is a descriptor -- wrapping it into a
built-in `property` (a completely different descriptor) will not work well
with the datastore (for example, you can't write GQL queries based on field
names that aren't really instances of `db.Property` but instances of
`property` \-- those fields are **not** in the datastore!).

So if you want to work with both the datastore _and_ for instances of `Model`
that have never actually been to the datastore and back, you'll have to choose
**two** names for what's logically "the same" field -- one is the name of the
attribute you'll use on in-memory model instances, and that one can be a
built-in `property`; the other one is the name of the attribute that ends up
in the datastore, and that one needs to be an instance of a `db.Property`
subclass _and_ it's this second name that you'll need to use in queries. Of
course the methods underlying the first name need to read and write the second
name, but you can't just "hide" the latter because that's the name that's
going to be in the datastore, and so that's the name that will make sense to
queries!

