diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py index 472d2c5c8e..0fa30d70c7 100644 --- a/django/contrib/auth/forms.py +++ b/django/contrib/auth/forms.py @@ -150,7 +150,7 @@ class UserChangeForm(forms.ModelForm): # Regardless of what the user provides, return the initial value. # This is done here, rather than on the field, because the # field does not have access to the initial value - return self.initial["password"] + return self.initial.get('password') class AuthenticationForm(forms.Form): diff --git a/docs/releases/2.1.2.txt b/docs/releases/2.1.2.txt index c0bcaf6b56..23632ad782 100644 --- a/docs/releases/2.1.2.txt +++ b/docs/releases/2.1.2.txt @@ -35,3 +35,6 @@ Bugfixes * Fixed a regression where sliced queries with multiple columns with the same name crashed on Oracle 12.1 (:ticket:`29630`). + +* Fixed a crash when a user with the view (but not change) permission made a + POST request to an admin user change form (:ticket:`29809`). diff --git a/tests/auth_tests/test_views.py b/tests/auth_tests/test_views.py index f29f5f0949..d12830ddc8 100644 --- a/tests/auth_tests/test_views.py +++ b/tests/auth_tests/test_views.py @@ -1221,6 +1221,7 @@ class ChangelistTests(AuthViewsTestCase): u = User.objects.get(username='testclient') u.is_superuser = False u.save() + original_password = u.password u.user_permissions.add(get_perm(User, 'view_user')) response = self.client.get(reverse('auth_test_admin:auth_user_change', args=(u.pk,)),) algo, salt, hash_string = (u.password.split('$')) @@ -1235,6 +1236,14 @@ class ChangelistTests(AuthViewsTestCase): ), html=True, ) + # Value in POST data is ignored. + data = self.get_user_data(u) + data['password'] = 'shouldnotchange' + change_url = reverse('auth_test_admin:auth_user_change', args=(u.pk,)) + response = self.client.post(change_url, data) + self.assertRedirects(response, reverse('auth_test_admin:auth_user_changelist')) + u.refresh_from_db() + self.assertEqual(u.password, original_password) @override_settings(