0

I'm busy with a plurasight course where I suppose to handle errors in Flask-wtf. The only problem is the course is a 'bit outdated. It's been made in 2014. In the video the teacher showed how you can define a validate() method in a class to use it first when I call form.validate_on_submit(). Here is the code:

from flask_wtf import FlaskForm
from wtforms.fields import StringField
from wtforms.fields.html5 import URLField
from wtforms.validators import DataRequired, url


class BookmarkForm(FlaskForm):
    url = URLField('url', validators=[DataRequired(), url()])
    description = StringField('description')

    def validate(self):
        if not self.url.data.startswith("http://") or self.url.data.startswith("https://"):
            self.url.data = "http://" + self.url.data

        if not FlaskForm.validate(self):
            return False

        if not self.description.data:
            self.description.data = self.url.data

        return True

And here is my view:

@app.route('/add', methods=['GET', 'POST'])
def add():
    form = BookmarkForm(request.form)
    if form.validate_on_submit():
        url = form.url.data
        description = form.description.data

        store_bookmark(url, description)
        flash('Stored bookmark {}'.format(description))
        return redirect(url_for('index'))
    return render_template('add.html', form=form)

The problem is, Flask-wtf don't let me submit a url like google.com. Only in this form: http://www.google.com.

Based on this description It should work like this:

validate_on_submit()

Call validate() only if the form is submitted. This is a shortcut for form.is_submitted() and form.validate()

But it doesn't. It still don't let me type a URL in without http://. I didn't find any solution in the documentation and here is a stackoverflow question, but there is no answer and it's also 3 years old. Please help me find out what I've done wrong!

Zaturek
  • 3
  • 4

1 Answers1

0

When rendered, a wtforms.UrlField creates an <input type="url"> element. Modern browsers will only accept valid absolute or relative urls in a url input element. A string like 'google.com' is not a valid absolute or relative url (it's a hostname), so the browser will not let you type it into the input.

To get around this, use a StringField instead of a UrlField so that an <input type="text"> is rendered, and the browser does not perform any validation.

class BookmarkForm(FlaskForm):
    url = StringField('url', validators=[DataRequired(), url()])
    description = StringField('description')

See also the answers to this question for some possible solutions on the browser side.

snakecharmerb
  • 47,570
  • 11
  • 100
  • 153