Python: db.ReferenceProperty collection_name callable?

6 views
Skip to first unread message

Oliver Zheng

unread,
May 22, 2009, 2:19:31 PM5/22/09
to Google App Engine
I'm trying to create a hierchy of kinds, the obvious reason of which
is that kinds can share model fields. However, for
ReferenceProperties, collection_name is fixed to when the model field
is declared in the model class. If this is declared in the parent
class, then all the children will have this collection name, which is
likely inaccurate:

class Parent(PolyModel):
house = db.ReferenceProperty(House, collection_name='parents')

class Child(Parent):
pass

House won't have a back reference to children in particular. And since
for PolyModels, fields cannot be overriden by children classes, Child
can't have its own house field.

This problem could be solved if collection_name was callable, so that
the children class could return its own collection name. Is there
plans for this?

Jeff S (Google)

unread,
May 26, 2009, 6:44:11 PM5/26/09
to Google App Engine
Hi Oliver,

Great suggestion and I want to make sure I understand the proposal. It
sounds like you would like the House model to have a parents back
reference and also a children back reference? How would the children
collection be given a collection name?

Here's some sample code to make this easier to follow:

from google.appengine.ext import db
from google.appengine.ext.db import polymodel

class House(db.Model):
address = db.IntegerProperty()

class Parent(polymodel.PolyModel):
house = db.ReferenceProperty(House, collection_name='parents')

class Child(Parent):
pass

h1 = House(address=5).put()
Parent(house=h1).put()
Child(house=h1).put()
Parent(house=h1).put()
h1 = db.get(h1)
h1.parents.fetch(5)

With the above code, the h1 House instance has 3 entities in its
parents back reference, 2 Parent instances and 1 Child instance.
Instead you would like only the 2 Parent classes to appear in
h1.parents? If that's the case, then you can do something like this
instead:

class Parent(polymodel.PolyModel):
house = db.ReferenceProperty(House, collection_name='parents')

class Child(Parent):
home = db.ReferenceProperty(House, collection_name='children')

h1 = House(address=5).put()
Parent(house=h1).put()
Child(home=h1).put()
Parent(house=h1).put()
h1 = db.get(h1)
h1.parents.fetch(5)
h1.children.fetch(5)

I'm guessing the above would be OK if it is acceptable that the
Child's reference to House is called 'home' instead of the parent
classes 'house'.

Thank you,

Jeff

Oliver Zheng

unread,
Jun 1, 2009, 9:17:46 PM6/1/09
to Google App Engine
Hi Jeff,

Thanks for the response. It's exactly the requirement (for the DRY
principal or whatever) to have houses for both parents and children.
It makes sense to select houses for either parents or children.

I am not sure how the collection_name back reference is implemented or
if it would even work if collection_name was callable. If it could
work, it might be something like:

class Parent(polymodel.PolyModel):
house = db.ReferenceProperty(House, collection_name=some_func)

class Child(Parent):
pass

and some how have some_func vary from when Parent is parsed and when
Child is parsed, so it returns 'parents' and 'children' respectively.
I actually have no idea how this could work. :)

Cheers,
Oliver
Reply all
Reply to author
Forward
0 new messages