diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py index d6b5702fff..ca7529ab5f 100644 --- a/django/contrib/auth/forms.py +++ b/django/contrib/auth/forms.py @@ -61,6 +61,11 @@ class UsernameField(forms.CharField): def to_python(self, value): return unicodedata.normalize('NFKC', super().to_python(value)) + def widget_attrs(self, widget): + attrs = super().widget_attrs(widget) + attrs['autocapitalize'] = 'none' + return attrs + class UserCreationForm(forms.ModelForm): """ diff --git a/tests/auth_tests/test_forms.py b/tests/auth_tests/test_forms.py index 825138755d..e12cf0161f 100644 --- a/tests/auth_tests/test_forms.py +++ b/tests/auth_tests/test_forms.py @@ -261,6 +261,10 @@ class UserCreationFormTest(TestDataMixin, TestCase): ['The password is too similar to the first name.'], ) + def test_username_field_autocapitalize_none(self): + form = UserCreationForm() + self.assertEqual(form.fields['username'].widget.attrs.get('autocapitalize'), 'none') + # To verify that the login form rejects inactive users, use an authentication # backend that allows them. @@ -439,6 +443,10 @@ class AuthenticationFormTest(TestDataMixin, TestCase): username_field = User._meta.get_field(User.USERNAME_FIELD) self.assertEqual(form.fields['username'].label, capfirst(username_field.verbose_name)) + def test_username_field_autocapitalize_none(self): + form = AuthenticationForm() + self.assertEqual(form.fields['username'].widget.attrs.get('autocapitalize'), 'none') + def test_username_field_label_empty_string(self): class CustomAuthenticationForm(AuthenticationForm): @@ -728,6 +736,10 @@ class UserChangeFormTest(TestDataMixin, TestCase): form = UserChangeFormWithoutPassword() self.assertNotIn('password', form.fields) + def test_username_field_autocapitalize_none(self): + form = UserChangeForm() + self.assertEqual(form.fields['username'].widget.attrs.get('autocapitalize'), 'none') + @override_settings(TEMPLATES=AUTH_TEMPLATES) class PasswordResetFormTest(TestDataMixin, TestCase):