SelectField:为什么返回 "Not a valid choice error"?

SelectField : why returning "Not a valid choice error"?

我在 python 方面很菜鸟,所以这可能是一个愚蠢的问题,对此深表歉意。

contact.html

{% extends 'layout.html' %}

{% block content %}

    <form method="POST" action="/">
    
       <fieldset class="form-field">
        {{ form.iro.label }}<br>
        {{ form.iro }}
        {% if form.iro.errors %}
          <ul class="errors">
            {% for error in form.iro.errors %}
            <li>{{ error }}</li>
            {% endfor %}
          </ul>
        {% endif %}
      </fieldset><br>
      
      {{ form.sub_issue }}

      </form>
  </div>

{% endblock %}

forms.py

from flask_wtf import FlaskForm
from wtforms import StringField, TextField, SubmitField, FieldList, FormField, SelectField, Form
from wtforms.validators import DataRequired, Length, Optional


class ContactForm(FlaskForm):
    """Contact form."""
    iro = SelectField(
        'IRO',
        choices=[]
    )
    
    sub_issue = SubmitField('Open an issue')

在我的代码中,我使用来自请求

的json填充了SelectField的选择参数
@app.route('/', methods=('GET', 'POST'))
def contact():
    form = ContactForm()
    if request.method == 'GET':
      r = requests.get("https://...",verify=False)
      form.iro.choices= [(iro,iro) for iro in list(r.json().values())]
      return render_template('contact.html', form=form)
    else:
      if form.validate_on_submit():
      #code when submitted...

但是当我点击提交按钮时,在我的 SelectField

下出现“不是有效的选择”错误

你知道为什么吗?

我无法对其进行测试,但对我来说所有的问题是您仅在 GET 中向 choices 添加值。当你 运行 validate_on_submit(): for POST 那么 choices 是空的,它总是会给出“不是一个有效的选择”

你需要这样的东西。

@app.route('/', methods=('GET', 'POST'))
def contact():
    form = ContactForm()

    r = requests.get("https://...", verify=False)
    form.iro.choices = [(iro,iro) for iro in list(r.json().values())]

    if request.method == 'GET':
      return render_template('contact.html', form=form)
    else:
      if form.validate_on_submit():
      #code when submitted...

如果requests总是得到相同的值那么你应该只在开始时读取它们一次(在contact()之外),写入本地文件或数据库并在contact()中读取它们

如果 requests 可能会给出不同的值,那么您应该在 GET 中读取它们,使用唯一名称保存在文件中(或使用唯一 ID 保存在数据库中)并将此 name/ID 发送到HTML 作为隐藏字段。稍后在 POST 你应该使用这个独特的 name/ID 来读取 file/database.

或多或少

@app.route('/', methods=('GET', 'POST'))
def contact():
    form = ContactForm()

    if request.method == 'GET':

      r = requests.get("https://...", verify=False)
      form.iro.choices = [(iro,iro) for iro in list(r.json().values())]

      save r.json() in unique file

      form.hidden_field = unique_file

      return render_template('contact.html', form=form)
    else:

      unique_file = form.hidden_field

      read r.json() from unique file

      form.iro.choices = [(iro,iro) for iro in list(r.json().values())]

      if form.validate_on_submit():
      #code when submitted...