【问题标题】:How to filter and display flask sqlalchemy one to many relationship data with jinja如何使用 jinja 过滤和显示烧瓶 sqlalchemy 一对多关系数据
【发布时间】:2020-01-19 08:06:52
【问题描述】:

我有两个 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

【问题讨论】:

    标签: python jinja2 flask-sqlalchemy one-to-many


    【解决方案1】:

    您需要指定要查看的属性,当前您引用的是整个对象,而不是字符串或整数,这也是要表示的内容。

    <!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>
    

    对此还有一些注意事项:

    艺术家蛞蝓是独一无二的吗?因为看起来您有多个艺术家使用相同的 slug 并且每个艺术家都有一首歌曲。让一首歌曲具有artist_idartist 关系,然后给艺术家一个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} %}引用模板中的歌曲

    【讨论】:

    • 如果我使用 {% for song in song %}
    • {{ song.song_info.title }}
    • {% endfor %} 它不会给出任何输出。但是如果我硬编码为 {{ song.song_info[0].title }},{{ song.song_info[1].title }} 等等,那么输出就来了。
  • 所以你的意思是song_info 实际上是一个列表。你需要两个嵌套的 for 循环,` {% for song in song %} {% for info in song.song_info %}
  • {{ info.title }}
  • {% endfor %} {% endfor %}` 但问题可能是你想如何清楚地格式化它
  • 当然是答案。你解决了我的问题。我之前在这里做了一些嵌套的forloops,但是它们都是错误的。你给了正确的。 Ruben Helsloot,非常感谢您,先生。
  • 猜你喜欢
    相关资源
    最近更新 更多
    热门标签