以下是我的模特:
class User(db.Model):
id = db.StringProperty(required=True)
created = db.DateTimeProperty(auto_now_add=True)
updated = db.DateTimeProperty(auto_now=True)
name = db.StringProperty(required=True)
email = db.StringProperty()
class Page(db.Model):
id = db.StringProperty(required=True)
created = db.DateTimeProperty(auto_now_add=True)
updated = db.DateTimeProperty(auto_now=True)
name = db.StringProperty(required=True)
link = db.StringProperty(required=True)
class UserPage(db.Model):
user = db.ReferenceProperty(User, collection_name='pages')
page = db.ReferenceProperty(Page, collection_name='users')
如何构建查询以查找用户页面?
我发现了一篇描述一种方法的文章,但这是最好的方法吗? http://blog.arbingersys.com/2008/04/google-app-engine-better-many-to-many.html
答案 0 :(得分:3)
您的答案将有效,但它会对数据存储区执行7次调用:
另一种只对数据存储区进行3次调用的方法是:
myuser = User.get_by_key_name("1")
up = UserPage.all().filter('user =', myuser).fetch(5)
keys = [UserPage.page.get_value_for_datastore(x) for x in up]
pages = db.get(keys)
for p in pages:
self.response.out.write(p.id)
有关详细信息,请参阅http://blog.notdot.net/2010/01/ReferenceProperty-prefetching-in-App-Engine。
答案 1 :(得分:1)
经过一些测试,似乎我可以使用:
myuser = User.get_by_key_name("1")
up = UserPage.all().filter('user =', myuser).fetch(5)
for x in up:
self.response.out.write(x.page.id)
答案 2 :(得分:1)
我会建议采用不同的方法,这种方法不是“关系导向”而是UserPage
关系:
class User(db.Model):
id = db.StringProperty(required=True)
created = db.DateTimeProperty(auto_now_add=True)
updated = db.DateTimeProperty(auto_now=True)
name = db.StringProperty(required=True)
email = db.StringProperty()
class Page(db.Model):
id = db.StringProperty(required=True)
created = db.DateTimeProperty(auto_now_add=True)
updated = db.DateTimeProperty(auto_now=True)
name = db.StringProperty(required=True)
link = db.StringProperty(required=True)
# Users linking to this page
users = db.ListProperty(db.Key)
然后,您可以使用以下查询获取特定用户的所有页面:
Page.gql("WHERE users = :1", user.key())
请注意,您应将键的列表属性放在您希望减少项目的一侧。我假设您的页面用户数量少于链接到用户的页面,因此我将其放在Page
方面,但这取决于您的具体用例。
请点击此处查看有关多对多主题的官方建议:http://code.google.com/appengine/articles/modeling.html