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

回答

3

你的回答將工作,但它會執行7調用數據存儲:

  • 1調用用戶。 get_by_key_name()
  • 1用於該呼叫到UserPage ...取()
  • 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

+0

哦很不錯的!我不知道這個循環太貴了。 Thx的擡頭。 – johnnytee 2010-09-09 12:03:37

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) 
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

+0

Thx這種方法和文章。我會用它做一些測試。 – johnnytee 2010-09-15 12:06:46

+0

再次感謝,我最終採用這種方法。 – johnnytee 2010-09-17 14:05:01