WTForms 试图将我的元组读取为 SQLAlchemy 行对象并抛出错误

WTForms is trying to read my tuples as SQLAlchemy row objects and throwing an error

我正在尝试编写一个应用程序,允许用户查看播放列表,然后将歌曲添加到播放列表(仅当歌曲不在播放列表中时)。我在 Flask 中使用 SQLAlchemy 和 WTForms 来执行此操作。

我的应用路线代码是:

playlist = Playlist.query.get_or_404(playlist_id)
    form = NewSongForPlaylistForm()


    curr_on_playlist = [s.id for s in playlist.songs]
    choices = (db.session.query(Song.id, Song.title).filter(Song.id.notin_(curr_on_playlist)).all())
    
    for choice in choices:
        choice = tuple(choice)
        print(type(choice), "*****************************")
        print(type(choices[0]))

打印让我知道,在选择被分配成为一个元组之后,它显示为一个元组,但是当下一行运行时(在选择列表中打印 0-index 选择),它得到作为 sqlalchemy 行对象返回。

这是一个问题,因为它试图将行对象作为唯一值传递(而不是将其视为具有值和标签的元组)。反过来,因为我在WTForms字段中有强制'int':

class NewSongForPlaylistForm(FlaskForm):
    """Form for adding a song to playlist."""

    song = SelectField('Song To Add', coerce=int)

当我拿走 coerce=int 时,表单正确填写,但每个条目在 HTML 中呈现如下:

<option value="(1, 'learning to fly')">(1, 'learning to fly')</option>
<option value="(2, 'learning to fly')">(2, 'learning to fly')</option>

而不是将元组拆分为整数值和字符串标签。

有人知道为什么元组又变成行了吗?此外,我如何让它们保持元组?他们不应该已经是元组了吗?谢谢!

列表理解应该有所帮助:

curr_on_playlist = [s.id for s in playlist.songs]
result = (db.session.query(Song.id, Song.title).filter(Song.id.notin_(curr_on_playlist)).all())
choices = [(x.id, x.title) for x in result]

现在选择将是元组列表 [(1, 'Example'), (2, 'Other')]wtforms 应该很乐意处理。

另一方面——您可能应该研究一下 from wtforms.ext.sqlalchemy.orm import QuerySelectField,它可以让您直接处理 SQLAlchemy 模型,而不必在 int 之间进行转换。