Question

Is it possible to populate a password field in wtforms in flask?

I've tried this:

capform = RECAPTCHA_Form() 
capform.username.data = username
capform.password.data = password

The form is defined like:

class RECAPTCHA_Form(Form):
    username = TextField('username', validators=[DataRequired()])
    password = PasswordField('password', validators=[DataRequired()])
    remember_me = BooleanField('Remember me.')
    recaptcha = RecaptchaField()        

The template looks like this:

<form method="POST" action="">
  {{ form.hidden_tag() }}
  {{ form.username(size=20) }}
  {{ form.password(size=20) }}
  {% for error in form.recaptcha.errors %}
     <p>{{ error }}</p>
  {% endfor %}
  {{ form.recaptcha }}
  <input type="submit" value="Go">
</form>             

I have tried to change the PasswordField to a TextField, and then it works.

Is there some special limitation to populating PasswordFields in wtforms?

Was it helpful?

Solution 2

Something I've found with Flask, and Flask apps in general, is that the source is the documentation. Indeed, it looks like by default you cannot populate the field. You can pass an argument hide_value to prevent this behavior.

This is a good call, since if you can populate the field, you have access to the raw password... which could be dangerous.

class PasswordInput(Input):
    """
    Render a password input.

    For security purposes, this field will not reproduce the value on a form
    submit by default. To have the value filled in, set `hide_value` to
    `False`.
    """
    input_type = 'password'

    def __init__(self, hide_value=True):
        self.hide_value = hide_value

    def __call__(self, field, **kwargs):
        if self.hide_value:
            kwargs['value'] = ''
        return super(

OTHER TIPS

Update: After looking through the WTForms docs I found an even better solution. There is a widget arg.

from wtforms import StringField
from wtforms.widgets import PasswordInput

class MyForm(Form):
     # ...

     password = StringField('Password', widget=PasswordInput(hide_value=False))

As yuji-tomita-tomita pointed out, the PasswordInput class (source) has an hide_value argument, however the constructor of PasswordField (source) does not forward it to the PasswordInput. Here is a PasswordField class that initializes PasswordInput with hide_value=False:

from wtforms import widgets
from wtforms.fields.core import StringField


class PasswordField(StringField):
    """
    Original source: https://github.com/wtforms/wtforms/blob/2.0.2/wtforms/fields/simple.py#L35-L42

    A StringField, except renders an ``<input type="password">``.
    Also, whatever value is accepted by this field is not rendered back
    to the browser like normal fields.
    """
    widget = widgets.PasswordInput(hide_value=False)

I believe there is an easier way to access the data of the password field, without usinghide_value. In your view, simply add in the request data as an argument to the form's constructor:

from flask import request    

capform = RECAPTCHA_Form(request.form) 
capform.username.data = username
capform.password.data = password

This should make the password input available for validation, and to be used in testing if desired.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top