1

我在带有烧瓶的 wtforms 中使用字段列表,但它们的默认值无法正确呈现。

在下面的示例中,Fieldlist 的 min_entries 值为 1,我通过 append_entry() 方法添加了两个额外的条目。

额外的两个条目无法正确呈现,因为它们的值不再是默认值,而是一些混合了 html 和默认值的丑陋文本。

现在我决定在我的项目中根本不使用字段列表,而是通过 min_entries 生成固定数量的条目,这意味着我不能使用动态数量的条目。

flask 如何呈现 Fieldlist 条目

第一个条目:value="[Enter track number]"
第二个条目:value="<input id="track" name="track" type="text" value="[Enter track number]">"

如何呈现 FieldList 条目

依赖关系和文件夹树

  • 烧瓶:1.0.2
  • 烧瓶引导:3.3.7.1
  • 烧瓶-wtf:0.14.2

文件夹结构:
├── app.py
├── templates
| └── album_add.html

应用程序.py

# Load and initialise flask variables
app = Flask(__name__)
SECRET_KEY = os.urandom(32); app.config['SECRET_KEY'] = SECRET_KEY
bootstrap = Bootstrap(app)

# form
class TrackShortList(FlaskForm):
    song_index = SelectField('Select Track')
    track_number = StringField('Track number', default='[Enter track number]')
    def __init__(self, csrf_enabled=False, *args, **kwargs):
        super(TrackShortList, self).__init__(csrf_enabled=csrf_enabled, *args, **kwargs) # required to disable csrf otherwise 'CSRF Token' is displayed
        # see https://stackoverflow.com/questions/15649027/wtforms-csrf-flask-fieldlist
class selectTracks(FlaskForm):
    tracks = FieldList(FormField(TrackShortList), min_entries=1)

# route
@app.route('/addtrack', methods=['post','get'])
def addtrack():
    track_select = [("Select track",)*2, ("A track",)*2, ("Another track",)*2]
    form = selectTracks()
    for i in range(2):
        trackChildForm = TrackShortList()
        form.tracks.append_entry(trackChildForm)
    for sub_form in form.tracks:
        sub_form.song_index.choices = track_select  
    if form.validate_on_submit():
        pass
    return render_template('album_add.html', form=form)

专辑添加.html

{% import "bootstrap/wtf.html" as bswtf %}    
<div class='form'>
    <form method="POST">
        {{ form.hidden_tag() }}
        {% for track_select in form.tracks %}
        <tr>
            {% for field in track_select  %}
                <td>{{ bswtf.form_field(field) }}</td>
            {% endfor %}
         </tr>
         <hr>
        {% endfor %}
</div>
4

2 回答 2

1

下面的路线有效。

不同之处在于我假设这条线trackChildForm.track_number = '[Enter track number]'会覆盖默认的 TrackShortList.track_number 值。

我通过查看此处解释的类似问题找到了此解决方案。但我不知道为什么它会起作用,所以欢迎任何澄清。

@app.route('/addtrack_working', methods=['post','get'])
def addtrack_working():
    track_select = [("Select track",)*2, ("A track",)*2, ("Another track",)*2]
    form = selectTracks()
    for i in range(2):
        trackChildForm = TrackShortList()
        trackChildForm.track_number = '[Enter track number]'
        form.tracks.append_entry(trackChildForm)
    for sub_form in form.tracks:
        sub_form.song_index.choices = track_select
    if form.validate_on_submit():
        pass
    return render_template('album_add.html', form=form)
于 2019-01-02T11:46:58.190 回答
0

append_entry类需要数据,不是表单。如果未提供数据,则添加已定义表单的空实例。

因此,对于您的用例,就像:

track_select = [("Select track",)*2, ("A track",)*2, ("Another track",)*2]
form = selectTracks()
for i in range(2):
    form.tracks.append_entry()
for sub_form in form.tracks:
    sub_form.song_index.choices = track_select
if form.validate_on_submit():
    pass
return render_template('album_add.html', form=form)
于 2019-03-06T12:36:41.310 回答