1
votes

I am working on a flask website with MongoDB as the DB at the backend. I am stuck with an error which I am not able to resolve.

I am creating a Flask WTF RadioField with dynamic choices (queried from a MongoDB collection which has a list of patients admitted to a hospital):

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

The view function is like this:

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)

My HTML is like this:

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

I can render the form with out any problem and can also see the various choices. when I click (select) a RadioField option and hit on "Submit" button, I get the following prints indicating validate_on_submit() failed:

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

The situation I am facing is very similar to the below question, but the solution suggested does'nt work for me.

Not a Valid Choice for Dynamic Select Field WTFORMS

1

1 Answers

0
votes

Your problem may be one of these two things; the easiest (but I don't think this is the one) is that your validation does not know the choices before validation so try this:

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)

As I commented that still may fail, and without testing I cant confirm. You might, instead want to build a dynamic form in this way:

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()