我有3个模特帖子,评论,用户:
class User(UserMixin, db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), unique=True, index=True)
posts = db.relationship('Post', backref='author', lazy='dynamic')
comments = db.relationship('Comment', backref='author', lazy='dynamic')
class Post(db.Model):
__tablename__ = 'posts'
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.Text)
author_id = db.Column(db.Integer, db.ForeignKey('users.id'))
comments = db.relationship('Comment', backref='post', lazy='dynamic')
class Comment(db.Model):
__tablename__ = 'comments'
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.Text)
author_id = db.Column(db.Integer, db.ForeignKey('users.id'))
post_id = db.Column(db.Integer, db.ForeignKey('posts.id'))
我的问题: 如何过滤那些未被给定用户评论的帖子(给定user.id)
我有一段代码用于过滤由给定用户评论的帖子:
@property
def commented_posts(self):
return Post.query.join(Comment, Comment.post_id==Post.id).filter(Comment.author_id==self.id)
答案 0 :(得分:0)
查找给定用户未在给定帖子上发表评论的所有帖子:
db.session.query(Post)\
.filter(~exists().where(and_(Comment.author_id != some_user_id, Post.id == Comment.post_id))).all()
这会生成sql:
SELECT posts.id AS posts_id, posts.body AS posts_body, posts.author_id AS posts_author_id
FROM posts
WHERE NOT (EXISTS (SELECT *
FROM comments
WHERE comments.author_id != :author_id_1 AND posts.id = comments.post_id))
示例测试代码:
from sqlalchemy import exists, and_
u1 = User(username='User1')
u2 = User(username='User2')
db.session.add_all([u1, u2])
db.session.commit()
p1 = Post(body='Post1', author_id=u1.id, comments=[Comment(body='Comment1', author_id=u1.id),
Comment(body='Comment2', author_id=u2.id)])
p2 = Post(body='Post2', author_id=u2.id, comments=[Comment(body='Comment3', author_id=u1.id)])
p3 = Post(body='Post3', author_id=u2.id)
db.session.add_all([p1, p2, p3])
db.session.commit()
result = db.session.query(Post)\
.filter(~exists().where(and_(Comment.author_id != u1.id, Post.id == Comment.post_id))).all()
# Returns post 2 and post 3
print(result)
result = db.session.query(Post)\
.filter(~exists().where(and_(Comment.author_id != u2.id, Post.id == Comment.post_id))).all()
# Returns post 3
print(result)