Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validating GET Params with WTForms in Flask

I have spent a couple of days trying to get WTForms to validate my request.args, but I just can not get form.validate() to return True.

The idea is that I have a simple text field for user input in a WTForm as shown below.

form.py

class SearchForm(FlaskForm):
    q = StringField('q',
                           validators=[])
    search = SubmitField('Search')

    def validate_q(self, q):
        if q.data not in allowed_values: #"allowed_values" is just a list I want to check against
            raise ValidationError('')

search.html

<form method="GET" action="{{ url_for('finance.search') }}">
  <div class="col-9 col-md-5 p-0 m-0">
    {% if form.q.errors %} {{ form.q(class="form-control form-control-md is-invalid") }}
    <div class="invalid-feedback">
      {% for error in form.q.errors %}
      <span>{{ error }}</span> {% endfor %}
    </div>
    {% else %} {{ form.q(class="form-control form-control-md") }} {% endif %}
  </div>
  <div class="col-2 col-md-2 p-0">
    {{ form.search(class="btn btn-md btn-dark") }}
  </div>
</form>

routes.py

@finance.route('/finance/search')
def search():
    form = SearchForm(request.args)
    print(form.validate()) #always gives false

The HTML code for the form is included on several templates and submitting the form always directs to the search route that is shown below. I tried following WTForms documentation and passed in request.args into the form. When I ran the .validate() on the object, the validate function for the q parameter also executed, but for some reason .validate() always returns False.

Can anyone please elaborate on why that might be? I know I can use post request, or add a custom validation function inside the route, but I want to avoid workarounds if possible.

(stack-overflow seems to use a similar type of architecture for their search http://127.0.0.1:8000/finance/search?q=aapl&search=Search vs https://stackoverflow.com/search?q=aapl and I want to follow that if possible.)

Thanks!

like image 477
sarartur Avatar asked Apr 09 '26 16:04

sarartur


1 Answers

I actually just figured out that the error was happening because I was not including a crsf_token in the form. The token is not needed since the its a get request, but this needs to be explicitly stated with meta = {'csrf': False}.

@finance.route('/finance/search')
def search():
    form = SearchForm(request.args, meta={'csrf': False})
    print(form.validate()) #Now gives True if validation function does not raise error
like image 187
sarartur Avatar answered Apr 11 '26 05:04

sarartur