2015-12-16 229 views
0

以下是一個基本示例 - 帖子歸用戶所有並且很受用戶歡迎。如何爲特定用戶選擇喜歡的帖子?Peewee:通過多對多關係過濾

import datetime 
import peewee 

class User(peewee.Model): 
    name = peewee.CharField(max_length=200) 

class Post(peewee.Model): 
    user = peewee.ForeignKeyField(User) 
    text = peewee.TextField() 

class Like(peewee.Model): 
    user = peewee.ForeignKeyField(User) 
    post = peewee.ForeignKeyField(Post) 
    time = peewee.DateTimeField(default=datetime.datetime.now) 

我做一個查詢從象模型的角度來看,用Like.select()開始查詢,並加入Post模型。可以嗎?我如何從Post模型的角度來查詢,即Post.select()...

這裏有一個舒適的完整示例:

def check_likes(): 
    user, _ = User.get_or_create(name="John") 
    post, _ = Post.get_or_create(text="Hello world!", user=user) 
    like, _ = Like.get_or_create(post=post, user=user) 

    print("Created: ", user, post, like) 

    # Get liked posts for user 
    query_likes = (Like.select() 
     .where(Like.user == user) 
     .join(User) 
     .join(Post)) 
    liked_posts = [like.post for like in query_likes] 

    print("Liked posts: ", liked_posts) 

if __name__ == '__main__': 
    User.create_table(True) 
    Post.create_table(True) 
    Like.create_table(True) 

    check_likes() 

UPD。我結束了這樣的查詢的時刻:

def liked_by(user_id): 
    """Active posts liked by user.""" 
    return (Post.select(Post, User, Like) 
     .join(User, on=(Post.user == User.id)) 
     .switch(Post) 
     .join(Like, peewee.JOIN.LEFT_OUTER, 
       on=(Like.post == Post.id).alias('like')) 
     .where(Like.user == user_id) 
     .order_by(Like.time.desc())) 

回答

1

上述查詢應該工作,但你可能改一改:

Like.select(Like, Post)... 

您還需要考慮你是如何加入照顧表。使用 '開關' 的方法:

query_likes = (Like.select(Like, Post) # <<< Add like and post 
    .where(Like.user == user) 
    .join(User) 
    .switch(Like) # <<< You need this. 
    .join(Post)) 
liked_posts = [like.post for like in query_likes] 

你也可以這樣做:

Post.select().join(Like).where(Like.user == some_user) 
+0

謝謝查爾斯!在更新後的問題中,我最後用'likes_by()'作爲查詢。不知道這裏是否真的需要'JOIN.LEFT_OUTER'。 我還需要在我的真實代碼中指定'on'語句,不確定什麼時候需要它,但我使用UUID主鍵並且好像在某些情況下需要它,所以我決定將它添加到其他地方:) – rudyryk

+0

嗯..似乎在這裏實際上不需要'JOIN.LEFT_OUTER'。在另一種情況下可能需要 - 在不過濾的情況下查詢所有帖子+由特定用戶加入喜歡。對? – rudyryk