flask sqlalchemy如何用jinja过滤显示一对多关系数据
How to filter and display flask sqlalchemy one to many relationship data with jinja
我有两个 mysql 表(“song_info”和“djartist1”),它们具有一对多关系。我想显示来自单个艺术家的所有歌曲(来自特定用户的所有帖子)。但我得到的是一个列表,而不是我想要在 html 文件中显示的内容。你能给我一个解决方案吗?
这是与此问题相关的代码
#Parent
class Djartist1(db.Model):
id = db.Column(db.Integer, primary_key=True)
artistid = db.Column(db.Integer, nullable=False)
name = db.Column(db.String(30), nullable=False)
slug = db.Column(db.String(30), nullable=False)
dj_img_location = db.Column(db.String(250), nullable=True)
facebook = db.Column(db.String(200), nullable=True)
email = db.Column(db.String(50), nullable=True)
song_info = db.relationship('Song_info', backref='djartist1', lazy=True)
#Child
class Song_info(db.Model):
song_id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(60), nullable=False)
slug = db.Column(db.String(50), nullable=False)
artist = db.Column(db.String(60), nullable=True)
djartist = db.Column(db.String(20), nullable=True)
owner_id = db.Column(db.Integer, db.ForeignKey('djartist1.id'), nullable=False)
file_location_name = db.Column(db.String(250), nullable=False)
img_location_name = db.Column(db.String(250), nullable=False)
lyrics = db.Column(db.String(400), nullable=True)
dateadded = db.Column(db.String, nullable=False)
@app.route("/dj-artists/<string:dj_slug>.html", methods=['GET'])
def dj_artist(dj_slug):
artists2 = Djartist1.query.filter_by(slug=dj_slug).first()
songs = Djartist1.query.filter_by(slug=dj_slug).all()
return render_template('dj-artist.html', parameter=parameter, info=artists2, songs=songs)
这是html代码
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<h1>Hello</h1>
songs {{songs}}
<br>
<p>forloop for songs</p>
{% for song in songs %}
<li>{{ song.song_info }}</li>
{% endfor %}
</body>
</html>
这是我得到的html输出
Hello
songs [<Djartist1 3>]
forloop for songs
[<Song_info 4>, <Song_info 5>, <Song_info 6>, <Song_info 7>, <Song_info 8>, <Song_info 9>, <Song_info 10>, <Song_info 11>, <Song_info 12>]
以上数字正确。但是我需要的是那些数字(ID)的歌曲名称。
Jinja2 HTML code and the output
您需要指定要查看的属性,目前您引用的是整个对象,而不是字符串或整数,这也是所表示的内容。
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<h1>Hello</h1>
songs {{songs}}
<br>
<p>forloop for songs</p>
{% for song in songs %}
<li>{{ song.song_info.title }}</li>
{% endfor %}
</body>
</html>
对此还有一些注意事项:
艺术家鼻涕虫是否独一无二?因为看起来你有多个艺术家有相同的鼻涕虫,每个艺术家都有一首歌。让一首歌曲具有 artist_id
和 artist
关系,然后给艺术家一个 songs
属性会更有意义。这是一个例子:
class Customer:
id = Column(BigInteger, primary_key=True)
orders = relationship("Order", back_populates="customer")
class Order:
customer_id = Column(Integer, ForeignKey('customer.id'), nullable=False)
customer = relationship("Customer", innerjoin=True, back_populates="orders")
此外,如果每个 slug 只有一个 Djartist,则不需要进行多次查询。您可以将视图功能更改为
@app.route("/dj-artists/<string:dj_slug>.html", methods=['GET'])
def dj_artist(dj_slug):
artist = Djartist1.query.filter_by(slug=dj_slug).one()
return render_template('dj-artist.html', info=artist)
并通过{% for song in artist.songs} %}
引用模板中的歌曲
我有两个 mysql 表(“song_info”和“djartist1”),它们具有一对多关系。我想显示来自单个艺术家的所有歌曲(来自特定用户的所有帖子)。但我得到的是一个列表,而不是我想要在 html 文件中显示的内容。你能给我一个解决方案吗?
这是与此问题相关的代码
#Parent
class Djartist1(db.Model):
id = db.Column(db.Integer, primary_key=True)
artistid = db.Column(db.Integer, nullable=False)
name = db.Column(db.String(30), nullable=False)
slug = db.Column(db.String(30), nullable=False)
dj_img_location = db.Column(db.String(250), nullable=True)
facebook = db.Column(db.String(200), nullable=True)
email = db.Column(db.String(50), nullable=True)
song_info = db.relationship('Song_info', backref='djartist1', lazy=True)
#Child
class Song_info(db.Model):
song_id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(60), nullable=False)
slug = db.Column(db.String(50), nullable=False)
artist = db.Column(db.String(60), nullable=True)
djartist = db.Column(db.String(20), nullable=True)
owner_id = db.Column(db.Integer, db.ForeignKey('djartist1.id'), nullable=False)
file_location_name = db.Column(db.String(250), nullable=False)
img_location_name = db.Column(db.String(250), nullable=False)
lyrics = db.Column(db.String(400), nullable=True)
dateadded = db.Column(db.String, nullable=False)
@app.route("/dj-artists/<string:dj_slug>.html", methods=['GET'])
def dj_artist(dj_slug):
artists2 = Djartist1.query.filter_by(slug=dj_slug).first()
songs = Djartist1.query.filter_by(slug=dj_slug).all()
return render_template('dj-artist.html', parameter=parameter, info=artists2, songs=songs)
这是html代码
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<h1>Hello</h1>
songs {{songs}}
<br>
<p>forloop for songs</p>
{% for song in songs %}
<li>{{ song.song_info }}</li>
{% endfor %}
</body>
</html>
这是我得到的html输出
Hello
songs [<Djartist1 3>]
forloop for songs
[<Song_info 4>, <Song_info 5>, <Song_info 6>, <Song_info 7>, <Song_info 8>, <Song_info 9>, <Song_info 10>, <Song_info 11>, <Song_info 12>]
以上数字正确。但是我需要的是那些数字(ID)的歌曲名称。
Jinja2 HTML code and the output
您需要指定要查看的属性,目前您引用的是整个对象,而不是字符串或整数,这也是所表示的内容。
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<h1>Hello</h1>
songs {{songs}}
<br>
<p>forloop for songs</p>
{% for song in songs %}
<li>{{ song.song_info.title }}</li>
{% endfor %}
</body>
</html>
对此还有一些注意事项:
艺术家鼻涕虫是否独一无二?因为看起来你有多个艺术家有相同的鼻涕虫,每个艺术家都有一首歌。让一首歌曲具有 artist_id
和 artist
关系,然后给艺术家一个 songs
属性会更有意义。这是一个例子:
class Customer:
id = Column(BigInteger, primary_key=True)
orders = relationship("Order", back_populates="customer")
class Order:
customer_id = Column(Integer, ForeignKey('customer.id'), nullable=False)
customer = relationship("Customer", innerjoin=True, back_populates="orders")
此外,如果每个 slug 只有一个 Djartist,则不需要进行多次查询。您可以将视图功能更改为
@app.route("/dj-artists/<string:dj_slug>.html", methods=['GET'])
def dj_artist(dj_slug):
artist = Djartist1.query.filter_by(slug=dj_slug).one()
return render_template('dj-artist.html', info=artist)
并通过{% for song in artist.songs} %}