【问题标题】:Peewee: filtering by many-to-many relationshipPeewee:按多对多关系过滤
【发布时间】:2015-12-21 17:15:26
【问题描述】:

这是一个基本示例 - 帖子由用户拥有和喜欢。如何为特定用户选择喜欢的帖子?

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 模型的角度进行查询,以 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()))

【问题讨论】:

    标签: python orm peewee


    【解决方案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)
    

    【讨论】:

    • 谢谢查尔斯!在更新的问题中,我最终得到了liked_by() 中的查询。不确定我是否真的需要JOIN.LEFT_OUTER。我还需要在我的真实代码中指定 on 语句,不确定何时需要,但我使用 UUID 主键并且在某些情况下似乎需要它,所以我决定在任何地方添加它:)
    • 嗯...似乎实际上不需要JOIN.LEFT_OUTER。在另一种情况下可能需要它 - 查询所有帖子而不过滤+特定用户的加入喜欢。对吗?
    猜你喜欢
    • 2017-04-26
    • 2013-12-03
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 2020-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多