Reference Property Details

Consider the following class that maps authors to articles for a personal library site:

class ArticleAuthors(db.Model):
    article= ReferenceProperty(Article)
    author = ReferenceProperty(Author)

One could use such a class to get a list of all authors for a particular article:

        articleAuthors = db.GqlQuery("Select author from ArticleAuthors where article=:1", article)  # article has been accessed earlier

This is not too difficult, but there is another way to do it because of how the App Engine library Model class works. When a ReferenceProperty B is defined within a class A, it provides B with a property A_set which is the set of all As with a matching B. Whew!

For our example, class Article is given a property articleauthor_set, and class Author is given a property articleauthor_set.

If you have a particular article, you can get all its ArticleAuthor mappings with

    articleAuthors = article.articleauthor_set

You could get the authors with:

    authors = aa.author for aa in article.articleauthor_set

or with the long-hand version:

    authors = []
    for aa in article.articleauthor_set:
        authors.append(aa.author)

Now one might argue that this short-hand is more work than it's worth. And it even causes more problems. If you have two ReferenceProperty fields of the same type in a class, you'll get an error. For example, consider a Relationship table mapping two persons in a system:

    class Relationship(db.Model):
        person1 = ReferenceProperty(Person)
        person2 = ReferenceProperty(Person)

This will cause problems because class Person will be given two properties of the same name: relationship_set.

To fix this, you need to provide another parameter, collection_name, when you define the field:

    
class Relationship(db.Model):
        initiator = ReferenceProperty(Person,collection_name='initiator_set')
        acceptor = ReferenceProperty(Person, collection_name='acceptor_set')


Assume a particular person can show up as either an initiator or acceptor in a relationship. Then to find all the relations of a particular person, we need to

    relations = []
    for relation in person.initiator_set:
        relations.append(relation.acceptor)
    for relation in person.acceptor_set:
        relations.append(relation.initiator)

    

Recent site activity