title: Apply Autocomplete=off to Django password reset confirm form
body: <p>I am using Django 2.2 with Python 3.7</p>
  
  <p>Following a security audit, I have been asked to ensure all security-related fields on forms in our application render with the autocomplete="off" attribute. Whether or not this is a valid and useful security measure is out of scope... unfortunately. So far, I have accomplished this by extending the form in question. For example, with the PasswordResetForm (where the user enters the email associated with the account):</p>
  
  <pre class="lang-py prettyprint-override"><code>class NoAutocompletePasswordResetForm(PasswordResetForm):
      def __init__(self, *args, **kwargs):
          super(PasswordResetForm, self).__init__(*args, **kwargs)
          self.fields['email'].widget.attrs.update({'autocomplete': 'off'})
  </code></pre>
  
  <p>And then instructing the relevant auth view to use it like so (in urls.py):</p>
  
  <pre class="lang-py prettyprint-override"><code>    url(r'^accounts/password_reset/?$', auth_views.PasswordResetView.as_view(form_class=forms.NoAutocompletePasswordResetForm)),
  </code></pre>
  
  <p>This worked fine up until the Password Reset Confirm View, which uses the SetPasswordForm. The first attempt there went something like this:</p>
  
  <pre class="lang-py prettyprint-override"><code>url(r'^accounts/reset/(?P&lt;uidb64&gt;[0-9A-Za-z]+)/(?P&lt;token&gt;[0-9A-Za-z\-]+)/$', auth_views.PasswordResetConfirmView.as_view(form_class=forms.NoAutocompleteSetPasswordForm)),
  
  class NoAutocompleteSetPasswordForm(SetPasswordForm):
      def __init__(self, *args, **kwargs):
          super(SetPasswordForm, self).__init__(*args, **kwargs)
          self.fields['new_password1'].widget.attrs.update({'autocomplete': 'off'})
          self.fields['new_password2'].widget.attrs.update({'autocomplete': 'off'})
  </code></pre>
  
  <p>However this just yields a TypeError, on the super() line, with the detail that <code>__init__() got an unexpected keyword argument 'user'</code>, despite the presence of a named <code>user</code> argument to the init of that form, as seen <a href="https://github.com/django/django/blob/master/django/contrib/auth/forms.py" rel="nofollow noreferrer">in the Django source</a>. But for funsies, I tried passing the user as a positional arg instead, like so:</p>
  
  <pre class="lang-py prettyprint-override"><code>class NoAutocompleteSetPasswordForm(SetPasswordForm):
      def __init__(self, *args, **kwargs):
          myKwargs = kwargs.copy()
          myUser = myKwargs['user']
          del myKwargs['user']
  
          myArgs = (*args, myUser)
  
          super(SetPasswordForm, self).__init__(*myArgs, **myKwargs)
          self.fields['new_password1'].widget.attrs.update({'autocomplete': 'off'})
          self.fields['new_password2'].widget.attrs.update({'autocomplete': 'off'})
  </code></pre>
  
  <p>With this tweak, the form makes it through construction, but Django errs during template rendering instead. In particular, I get the following stack trace:</p>
  
  <pre><code>Internal Server Error: /accounts/reset/MjA/set-password/
  Traceback (most recent call last):
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 829, in _resolve_lookup
      current = current[bit]
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\forms\boundfield.py", line 66, in __getitem__
      raise TypeError
  TypeError
  
  During handling of the above exception, another exception occurred:
  
  Traceback (most recent call last):
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
      response = get_response(request)
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\core\handlers\base.py", line 145, in _get_response
      response = self.process_exception_by_middleware(e, request)
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\core\handlers\base.py", line 143, in _get_response
      response = response.render()
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\response.py", line 106, in render
      self.content = self.rendered_content
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\response.py", line 83, in rendered_content
      content = template.render(context, self._request)
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\backends\django.py", line 61, in render
      return self.template.render(context)
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 171, in render
      return self._render(context)
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 163, in _render
      return self.nodelist.render(context)
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 937, in render
      bit = node.render_annotated(context)
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 904, in render_annotated
      return self.render(context)
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\defaulttags.py", line 309, in render
      return nodelist.render(context)
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 937, in render
      bit = node.render_annotated(context)
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 904, in render_annotated
      return self.render(context)
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 987, in render
      output = self.filter_expression.resolve(context)
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 671, in resolve
      obj = self.var.resolve(context)
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 796, in resolve
      value = self._resolve_lookup(context)
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 837, in _resolve_lookup
      current = getattr(current, bit)
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\forms\boundfield.py", line 74, in errors
      return self.form.errors.get(self.name, self.form.error_class())
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\forms\forms.py", line 180, in errors
      self.full_clean()
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\forms\forms.py", line 381, in full_clean
      self._clean_fields()
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\forms\forms.py", line 393, in _clean_fields
      value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
    File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\forms\widgets.py", line 258, in value_from_datadict
      return data.get(name)
  AttributeError: 'User' object has no attribute 'get'
  </code></pre>
  
  <p>So, how do I get this form to render with autocomplete='off'?</p>