鉴于这种多对多关系:
tagmap = db.Table('tagmap', db.Model.metadata,
db.Column('post_id', db.Integer, db.ForeignKey('posts.id'),
db.Column('tag_id', db.Integer, db.ForeignKey('tags.id'),)
class Post(db.Model):
__tablename__ = 'posts'
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.Text)
tags = db.relationship('Tag', secondary=tagmap, backref='posts')
class Tag(db.Model):
__tablename__ = 'tags'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
您将如何构造一个查询来选择所有帖子,包括关联标签对象的可迭代列表?
所需的查询结果结构:
[ <Post 1, "Blah", [<Tag "Goober">, <Tag "Mexico">]>,
<Post 2, "Daft Punk", [<Tag "French">]>,
<Post 3, "Slurpee", [<Tag "Diabetes">, <Tag "Tasty">, <Tag "Sugary">]>,
<Post 4, "Lasers", []> ]
Jinja 模板中期望的结果用法示例:
{% for post in posts %}
{{ post.text }}
<hr>
{% for tag in post.tags %}
{{ tag.name }},
{% endfor %}
{% endfor %}
编辑:
尝试扩展查询时,不再包含标签。请参阅下面的失败查询:
Post.query.join(User)\
.options(db.joinedload(Post.tags))\
.order_by(Post.create_date.desc()).limit(5)\
.values(User.name.label('author'),
Post.create_date,
Post.text,)
编辑 2:
所以这个查询很好用:
posts = db.session.query(Post, User.name.label('author')).join(User)\
.options(db.joinedload(Post.tags))\
.order_by(Post.created.desc()).limit(5)
但如果我想对 Post 中的列有选择性,我选择:
# I only need the post text, nothing else
posts = db.session.query(Post.text, User.name.label('author')).join(User)\
.options(db.joinedload(Post.tags))\
.order_by(Post.created.desc()).limit(5)
它开始迅速瓦解:
ArgumentError: Query has only expression-based entities - can't find property named 'tags'.
所以我尝试添加标签:
# Yes, I know this is wrong
posts = db.session.query(Post.text, Post.tags, User.name.label('author'))\
.join(User)\
.options(db.joinedload(Post.tags))\
.order_by(Post.created.desc()).limit(5)
仍然失败。
因此,如果您只想要父对象(Post)中的特定列,那么您在表达式中的哪个位置说“我仍然想要标签”?
现在它并不那么重要,但我认为知道它会很有用。或者甚至知道这是不可能的。