views:

125

answers:

2

I'm trying to access an object that is linked to by a db.ReferenceProperty in Google app engine. Here's the model's code:

class InquiryQuestion(db.Model):
    inquiry_ref = db.ReferenceProperty(reference_class=GiftInquiry, required=True, collection_name="inquiry_ref")

And I am trying to access it in the following way:

linkedObject = question.inquiry_ref

and then

linkedKey = linkedObject.key

but it's not working. Can anyone please help?

+3  A: 

The back reference is just a query. You need to use fetch() or get() to actually retrieve the entity or entities from the datastore:

linkedObject = question.inquiry_ref.get()

should do the trick. Or, you would use fetch() if you were expecting the back ref to refer to more than one entity.

Actually, the way that your class is constructed makes it ambiguous as to what exactly is happening here.

If you have a GiftInquiry entity, it will get an automatic property called inquiry_ref that will be a query (as I described above) that will return all InquiryQuestion entities that have their inquiry_ref property set to that GiftInquiry's Key.

On the other hand, if you have an InquiryQuestion entity, and you want to get the GiftInquiry entity to which its inquiry_ref property is set, you would do this:

linkedObject = db.get(question.inquiry_ref)

as the inquiry_ref is just the Key of the referred-to GiftInquiry, but that is not technically a BackReference.

Check out the explanation of ReferenceProperty and back references from the docs.

Adam Crossland
I tried the above: linkedObject = question.inquiry_ref.get() And I got the following error in my log: get() takes exactly 2 arguments (1 given) Traceback (most recent call last): File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/__init__.py", line 513, in __call__ handler.post(*groups) File "/base/data/home/apps/chowbird/1.342412733116965934/actions.py", line 126, in post linkedObject = question.inquiry_ref.get()TypeError: get() takes exactly 2 arguments (1 given)
jCuga
What is the type of question. Is it an InquiryQuestion or a GiftInquiry? I think that you probably want to use the second form: linkedObject = db.get(question.inquiery_ref).
Adam Crossland
+2  A: 

Your naming conventions are a bit confusing. inquiry_ref is both your ReferenceProperty name and your back-reference collection name, so question.inquiry_ref gives you a GiftInquiry Key object, but question.inquiry_ref.inquiry_ref gives you a Query object filtered to InquiryQuestion entities.

Let's say we have the following domain model, with a one-to-many relationship between articles and comments.

class Article(db.Model):
  body = db.TextProperty()

class Comment(db.Model):
  article = db.ReferenceProperty(Article)
  body = db.TextProperty()

comment = Comment.all().get()

# The explicit reference from one comment to one article
# is represented by a Key object
article_key = comment.article

# which gets lazy-loaded to a Model instance by accessing a property
article_body = comment.article.body

# The implicit back-reference from one article to many comments
# is represented by a Query object
article_comments = comment.article.comment_set

# If the article only has one comment, this gives us a round trip
comment = comment.article.comment_set.all().get()
Drew Sears