Reputation: 1
So, I have two models: Authors and Posts. Both have a boolean field 'status'. Posts are done by Authors, so the db.ReferenceProperty() field. The Models are these:
class Authors(db.Model):
status = db.BooleanProperty(default = True)
name = db.StringProperty(required = True)
class Posts(db.Model):
status = db.BooleanProperty(default = True)
title = db.StringProperty(required = True)
content = db.TextProperty(required = True)
author = db.ReferenceProperty(Authors)
So, I want to be able to list posts on my site when both status fields (the Posts and the Authors referenced) are set to True. If I set Authors.status to False, automatically all its child Posts will not be displayed anymore.
I know this doesn't work, but it would be something along these lines:
q = Posts.all()
q.filter('status =', True)
q.filter('author.status =', True)
q.run()
I know this is a JOIN and GAE datastore doesn't support joins, but any ideas of how I could possibly do that? Thanks in advance.
Upvotes: 0
Views: 89
Reputation: 599490
As you say, you can't do joins with the datastore. So you're restricted to iterating through and checking the status.
The exact way you do this is going to depend on your data. You probably want to query on authors first, then get the posts for each author with the right status:
all_posts = []
q = Authors.all().filter('status', True)
for author in q:
posts = Post.all().filter('author', author).filter('status', True)
all_posts.extend(posts.run())
Another way would be to get keys for all authors with status=True, put them in a set, then iterate through all posts and check if the author key is there:
all_posts = []
authors = set(Authors.all(keys_only=True).filter('status', True).run())
q = Post.all().filter('status', True)
for post in q:
if post._author in authors:
all_posts.append(post)
As I say, which is more efficient is going to depend on how many different authors you have, how many posts each has, and the distribution of statuses on each. Try them and check how many queries you're generating.
Upvotes: 1