'Fieldlist' / 'FormField' неправильно рендерится с flask_wtf - PullRequest
0 голосов
/ 31 декабря 2018

Я использую списки полей в wtforms с колбой, но их значения по умолчанию не отображаются правильно.

В приведенном ниже примере список полей имеет значение min_entries, равное 1, и я добавляю две дополнительные записи с помощью метода append_entry ().

Дополнительные две записи отображаются неправильно, поскольку их значение больше не является значением по умолчанию, а представляет собой некрасивый текст, который смешивает html и значение по умолчанию.

На данный момент я решил вообще не использовать списки полей в своем проекте, и вместо этого я генерирую фиксированное количество записей через min_entries, что означает, что я не могу использовать динамическое количество записей.

Как колба отображает записи списка полей

Первая запись: value="[Enter track number]"Вторая запись: value="<input id="track" name="track" type="text" value="[Enter track number]">"

How FieldList entries are rendered

Зависимости и дерево папок

  • Колба: 1.0.2
  • Flask-Bootstrap: 3.3.7.1
  • flask-wtf: 0.14.2

Структура папки:App── app.pyTemplates── шаблоны|Album── album_add.html

app.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)

album_add.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>

Ответы [ 2 ]

0 голосов
/ 06 марта 2019

Класс 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)
0 голосов
/ 02 января 2019

Маршрут, приведенный ниже, работает.

Разница в том, что эта строка 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)
...