即使使用coerce = ObjectId,也不是动态选择字段WTFORMS的有效选择

时间:2018-07-17 08:54:53

标签: python flask pymongo flask-wtforms

我正在一个烧瓶网站上,以 MongoDB 作为后端的数据库。 我遇到了无法解决的错误。

我正在创建具有动态选择的Flask WTF RadioField(从MongoDB集合中查询,该集合具有住院病人的列表):

`class PatientDevConnectForm(Form):
     patient = RadioField('Select patient', 
                           choices=[], 
                           coerce=ObjectId, 
                           validators=[DataRequired()])
     submit = SubmitField("Connect")`

视图功能如下:

def patientdev_connect():
     form = PatientDevConnectForm()
     if form.validate_on_submit():
          print("I am here")
          return render_template("home.html")
     else: 
          print(form.errors)
          print(form.patient.data)
          print(type(form.patient.data))

     pats = mongo.db.patients
     patients = pats.find()

     form.patient.choices = [(patient['_id'], patient['name']) for 
                                  patient in patients]
     return render_template("patientdev_connect.html", form=form)

我的HTML如下:

<form method="POST" action="">
{{ form.hidden_tag() }}
 <fieldset class="form-group">
    <div class="form-group">
      Select: {{ form.patient }}
    </div>
 </fieldset>

<div class="form-group">
  {{ form.submit(class="btn btn-outliner-info") }}
</div>

我可以毫无问题地呈现表单,还可以看到各种选择。当我单击(选择)RadioField选项并单击“提交”按钮时,我得到以下打印indicating validate_on_submit()失败:

{'patient': [u'Not a valid choice']}
5b433324a02d9b4bc99a106b
<class 'bson.objectid.ObjectId'>

我面临的情况与以下问题非常相似,但是建议的解决方案对我不起作用。

Not a Valid Choice for Dynamic Select Field WTFORMS

1 个答案:

答案 0 :(得分:0)

您的问题可能是这两件事之一;最简单的方法(但我不认为这是一种方法)是您的验证在验证之前不知道选择,因此请尝试以下操作:

def patientdev_connect():
     form = PatientDevConnectForm()
     # this attaches the choices to the form before validation but may overwrite..
     pats = mongo.db.patients
     patients = pats.find()
     form.patient.choices = [(patient['_id'], patient['name']) for 
                                  patient in patients]

     if form.validate_on_submit():
          print("I am here")
          return render_template("home.html")
     else: 
          print(form.errors)
          print(form.patient.data)
          print(type(form.patient.data))

     return render_template("patientdev_connect.html", form=form)

正如我评论的那样,它仍然可能会失败,并且未经测试我无法确认。您可能希望以这种方式构建动态表单:

def PatientDevConnectForm(**dynamic_kwargs):
    class PlaceholderForm(Form):
        patient = RadioField('Select patient', 
                              choices=[], 
                              coerce=ObjectId, 
                              validators=[DataRequired()])
        submit = SubmitField("Connect")
    pats = mongo.db.patients
    patients = pats.find()
    PlaceholderForm.patient.choices = [(patient['_id'], patient['name']) for 
                                  patient in patients]

    return PlaceholderForm()