解决Flask SQLAlchemy一对多关系下Jinja展示歌曲名称问题
解决方案:正确获取并展示艺术家的歌曲名称
咱们先定位问题根源:
- 后端获取歌曲的逻辑有误:你当前
songs = Djartist1.query.filter_by(slug=dj_slug).all()拿到的是艺术家对象列表,并非该艺术家关联的歌曲列表。 - 前端循环对象错误:你在循环艺术家对象,输出的是该艺术家关联的所有歌曲对象的字符串形式,而非单首歌曲的具体名称。
第一步:修复后端路由代码
既然已经通过artists2 = Djartist1.query.filter_by(slug=dj_slug).first()拿到了目标艺术家对象,直接通过它的song_info属性就能获取关联的所有歌曲(这是你在模型中定义db.relationship后自动生成的关联属性),无需重复查询。修改后的路由代码如下:
@app.route("/dj-artists/<string:dj_slug>.html", methods=['GET']) def dj_artist(dj_slug): artist = Djartist1.query.filter_by(slug=dj_slug).first() # 直接从艺术家对象获取关联歌曲列表,增加空值判断避免报错 songs = artist.song_info if artist else [] return render_template('dj-artist.html', info=artist, songs=songs)
注:我把变量名artists2改为artist,语义更贴合“单个艺术家”的场景;同时增加了空值判断,防止艺术家不存在时触发异常。
第二步:修复前端模板代码
现在songs已经是该艺术家对应的Song_info对象列表,只需在循环中直接访问歌曲的title属性,就能显示歌曲名称:
<!DOCTYPE html> <html> <head> <title>{{ info.name }}的歌曲</title> </head> <body> <h1>{{ info.name }}的歌曲列表</h1> {% if songs %} <ul> {% for song in songs %} <li>{{ song.title }}</li> {% endfor %} </ul> {% else %} <p>暂无歌曲</p> {% endif %} </body> </html>
额外优化建议
- 模型层面:可以给
Djartist1的relationship增加cascade参数,方便后续关联数据的批量操作(比如删除艺术家时自动删除其所有歌曲):song_info = db.relationship('Song_info', backref='djartist1', lazy=True, cascade="all, delete-orphan") - 模板层面:还可以展示更多歌曲信息,比如上传日期、歌词预览等,只需访问对应的属性即可,示例:
<li> {{ song.title }} - {{ song.dateadded }} {% if song.lyrics %} <p>歌词预览:{{ song.lyrics[:50] }}...</p> {% endif %} </li>
内容的提问来源于stack exchange,提问作者Thilina Wimalapriya
相关产品推荐
相关产品推荐

