Django password field input showing up as plaintext despite forms.PasswordInput declaration
<p>Django password field input showing up as plaintext despite <code>widget=forms.PasswordInput</code> declaration:</p>

<h1>forms.py</h1>

<pre><code>from django.contrib.auth.models import User
class LoginForm(forms.ModelForm):
    # specify password type so that passwords show up as *******, not plaintext
    # but this doesn't work if placeholder = ''
    password = forms.CharField(widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ["username", "password"]

    def __init__(self, *args, **kwargs):
        # first call the 'real' __init__()
        super(LoginForm, self).__init__(*args, **kwargs)
        # then do extra stuff:
        self.fields['username'].help_text = ''
        self.fields['password'].widget = forms.TextInput(attrs={'placeholder': ''})
        self.fields['password'].widget.attrs['class'] = 'form-control'
</code></pre>

<p>So interestingly, when I surface this form in a template, the <code>password</code> value shows up as plaintext instead of '******' text. But only if I add the <code>'placeholder': ''</code> line. I inspected the form element and figured out that when I added the  <code>'placeholder': ''</code> line, <code>type='password'</code> was being changed to <code>type='text'</code> in the <code>&lt;input type='FOO'&gt;&lt;/input&gt;</code>element in the rendered HTML.</p>

<p>--> How do I keep this from happening, so passwords continue to show up as plaintext, without removing my <code>'placeholder': ''</code> line?</p>

<p>You should not be using <code>forms.TextInput</code> for your password field. <a href="https://docs.djangoproject.com/en/1.10/ref/forms/widgets/#passwordinput" rel="nofollow">Django provides a PasswordInput widget</a> that is more appropriate. Try this:</p>

<pre><code>class Meta:
    model = User
    fields = ["username", "password"]

def __init__(self, *args, **kwargs):
    # first call the 'real' __init__()
    super(LoginForm, self).__init__(*args, **kwargs)
    # then do extra stuff:
    self.fields['username'].help_text = ''
    self.fields['password'].widget = forms.PasswordInput(attrs={'placeholder': ''})
    self.fields['password'].widget.attrs['class'] = 'form-control'
</code></pre>

<p>While you can edit the type of the field manually, it's better convention to use the widget.</p>

python django forms