2

这是我的模型:

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

4

3 回答 3

3

您的答案将起作用,但它将对数据存储执行 7 次调用:

  • 1 用于调用 User.get_by_key_name()
  • 1 用于调用 UserPage...fetch()
  • 5 对于循环内 x.page.id 的每个取消引用

另一种仅对数据存储进行 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

于 2010-09-09T01:43:20.280 回答
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)
于 2010-09-07T14:43:42.707 回答
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

于 2010-09-14T21:17:33.170 回答