views:

48

answers:

3

Hi,

I have the following model structure

class User(db.Model) :
nickname = db.StringProperty(required=True)
fullname = db.StringProperty(required=True)

class Article(db.Model) :
title = db.StringProperty(required=True)
body = db.StringProperty(required=True)
author = db.ReferenceProperty(User, required=True)

class Favorite(db.Model) :
who = db.ReferenceProperty(User, required=True)
what = db.ReferenceProperty(Article, required=True)


I'd like to display 10 last articles according to this pattern:

article.title, article.body, article.author(nickname), info if this article has been already favorited by the signed in user.

I have added a function which I use to get the authors of these articles using only one query (it is described here)

But I don't know what to do with the favorites (I'd like to know which of the displayed articles have been favorited by me using less than 10 queries (I want to display 10 articles)). Is it possible?

+1  A: 

You can actually do this with an amortized cost of 0 queries if you denormalize your data more! Add a favorites property to Authors which stores a list of keys of articles which the user has favorited. Then you can determine if the article is the user's favorite by simply checking this list.

If you retrieve this list of favorites when the user first logs in and just store it in your user's session data (and update it when the user adds/removes a favorite), then you won't have to query the datastore to check to see if an item is a favorite.


Suggested update to the Authors model:

class Authors(db.Model):  # I think this would be better named "User"
    # same properties you already had ...
    favorites = db.ListProperty(db.Key, required=True, default=[])

When the user logs in, just cache their list of favorites in your session data:

session['favs'] = user.favorites

Then when you show the latest articles, you can check if they are a favorite just by seeing if each article's key is in the favorites list you cached already (or you could dynamically query the favorites list but there is really no need to).

favs = session['favs']
articles = get_ten_latest_articles()
for article in articles:
    if article.key() in favs:
        # ...
David Underhill
Thank you for your advice. That's the solution I think.
Mateusz Cieslak
A: 

An alternative solution to dound's is to store the publication date of the favorited article on the Favorite entry. Then, simply sort by that when querying.

Nick Johnson
+1  A: 

I think there is one more solution.

Let's add 'auto increment' fields to the User and Article class.

Then, when we want to add an entry to the Favorite class, we will also add the key name in the format which we will be able to know having auto increment value of the signed in user and the article, like this 'UserId'+id_of_the_user+'ArticleId'+id_of_an_article.

Then, when it comes to display, we will easily predict key names of the favorites and would be able to use Favorite.get_by_key_name(key_names).

Mateusz Cieslak