diff --git a/django/contrib/auth/templates/auth/widgets/read_only_password_hash.html b/django/contrib/auth/templates/auth/widgets/read_only_password_hash.html
index b411298d74..a2a12c6f10 100644
--- a/django/contrib/auth/templates/auth/widgets/read_only_password_hash.html
+++ b/django/contrib/auth/templates/auth/widgets/read_only_password_hash.html
@@ -1,3 +1,5 @@
+
{% for entry in summary %}
-
{{ entry.label }}{% if entry.value %}: {{ entry.value }}{% endif %}
+{{ entry.label }}{% if entry.value %}: {{ entry.value }}{% endif %}
{% endfor %}
+
diff --git a/docs/releases/1.11.1.txt b/docs/releases/1.11.1.txt
index 41f82a0c63..26ff892731 100644
--- a/docs/releases/1.11.1.txt
+++ b/docs/releases/1.11.1.txt
@@ -30,3 +30,6 @@ Bugfixes
* Prevented ``SessionBase.cycle_key()`` from losing session data if
``_session_cache`` isn't populated (:ticket:`28066`).
+
+* Fixed layout of ``ReadOnlyPasswordHashWidget`` (used in the admin's user
+ change page) (:ticket:`28097`).
diff --git a/tests/auth_tests/test_forms.py b/tests/auth_tests/test_forms.py
index 68bcd892a1..05f1f41961 100644
--- a/tests/auth_tests/test_forms.py
+++ b/tests/auth_tests/test_forms.py
@@ -825,6 +825,22 @@ class ReadOnlyPasswordHashTest(SimpleTestCase):
html = widget.render(name='password', value=None, attrs={})
self.assertIn(_("No password set."), html)
+ @override_settings(PASSWORD_HASHERS=['django.contrib.auth.hashers.PBKDF2PasswordHasher'])
+ def test_render(self):
+ widget = ReadOnlyPasswordHashWidget()
+ value = 'pbkdf2_sha256$100000$a6Pucb1qSFcD$WmCkn9Hqidj48NVe5x0FEM6A9YiOqQcl/83m2Z5udm0='
+ self.assertHTMLEqual(
+ widget.render('name', value, {'id': 'id_password'}),
+ """
+
+ algorithm: pbkdf2_sha256
+ iterations: 100000
+ salt: a6Pucb******
+ hash: WmCkn9**************************************
+
+ """
+ )
+
def test_readonly_field_has_changed(self):
field = ReadOnlyPasswordHashField()
self.assertFalse(field.has_changed('aaa', 'bbb'))