#19611 closed Bug (duplicate)
User Admin breaks on submit with form validation error
Reported by: | Chris Wilson | Owned by: | nobody |
---|---|---|---|
Component: | contrib.auth | Version: | 1.5 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | yes | Patch needs improvement: | no |
Easy pickings: | yes | UI/UX: | no |
Description
Internal Server Error: /admin/users/ischooluser/4/ ... File "/home/installuser/Dropbox/projects/ischool/user_manager/django/django-1.5/django/utils/encoding.py", line 99, in force_text s = s.__unicode__() File "/home/installuser/Dropbox/projects/ischool/user_manager/django/django-1.5/django/forms/forms.py", line 411, in __str__ return self.as_widget() File "/home/installuser/Dropbox/projects/ischool/user_manager/django/django-1.5/django/forms/forms.py", line 458, in as_widget return widget.render(name, self.value(), attrs=attrs) File "/home/installuser/Dropbox/projects/ischool/user_manager/django/django-1.5/django/contrib/auth/forms.py", line 34, in render hasher = identify_hasher(encoded) File "/home/installuser/Dropbox/projects/ischool/user_manager/django/django-1.5/django/contrib/auth/hashers.py", line 135, in identify_hasher if len(encoded) == 32 and '$' not in encoded: Exception: Failed to render template: admin/change_form.html: Failed to render template: admin/includes/fieldset.html: object of type 'NoneType' has no len()
This happens when you click the Save button on the user edit form, but the form doesn't validate, so it tries to display again.
ReadOnlyPasswordHashWidget doesn't include any hidden fields, so there's no data bound to the field, but the form is still bound (because this is a POST request), so ReadOnlyPasswordHashField's bound_data returns None instead of the current password value:
> /home/installuser/Dropbox/projects/ischool/user_manager/django/django-1.5/django/contrib/auth/forms.py(32)render() -> if encoded == '' or encoded == UNUSABLE_PASSWORD: (Pdb) p encoded None (Pdb) up > /home/installuser/Dropbox/projects/ischool/user_manager/django/django-1.5/django/forms/forms.py(458)as_widget() -> return widget.render(name, self.value(), attrs=attrs) (Pdb) l 453 454 if not only_initial: 455 name = self.html_name 456 else: 457 name = self.html_initial_name 458 -> return widget.render(name, self.value(), attrs=attrs) 459 460 def as_text(self, attrs=None, **kwargs): 461 """ 462 Returns a string of HTML for representing this as an <input type="text">. 463 """ (Pdb) p self <django.forms.forms.BoundField object at 0xb2d7f56c> <bound method BoundField.value of <django.forms.forms.BoundField object at 0xb2d7f56c>> (Pdb) p self.form.is_bound True (Pdb) p self.form.data <QueryDict: {u'username': [u'smith'], u'first_name': [u''], u'last_name': [u''], u'account_type': [u''], u'_save': [u'Save'], u'last_login_0': [u'2012-01-24'], u'is_active': [u'on'], u'initial-date_joined_1': [u'11:44:56'], u'initial-date_joined_0': [u'2012-01-12'], u'last_login_1': [u'10:36:09'], u'is_staff': [u'on'], u'date_joined_0': [u'2012-01-12'], u'date_joined_1': [u'11:44:56'], u'groups': [u'2'], u'csrfmiddlewaretoken': [u'40e524bcd2d4864f044fe107266d55ba'], u'email': [u'john@smithy.example.com'], u'initial-last_login_0': [u'2012-01-24'], u'initial-last_login_1': [u'10:36:09']}> (Pdb) p self.name 'password' (Pdb) p self.form.initial {'username': u'smith', 'first_name': u'', 'last_name': u'', 'account_type': 1, 'is_active': True, 'is_superuser': False, 'is_staff': True, 'last_login': datetime.datetime(2012, 1, 24, 8, 36, 9, tzinfo=<UTC>), 'groups': [2], 'user_permissions': [], 'password': u'sha1$03d63$4ae1e7f3426c5c8bb4e008dea8d178f88a0c62ed', 'email': u'john@smithy.example.com', 'date_joined': datetime.datetime(2012, 1, 12, 9, 44, 56, tzinfo=<UTC>)} (Pdb) p self.form.initial.get('password') u'sha1$03d63$4ae1e7f3426c5c8bb4e008dea8d178f88a0c62ed' (Pdb) p self.field.bound_data <bound method ReadOnlyPasswordHashField.bound_data of <django.contrib.auth.forms.ReadOnlyPasswordHashField object at 0xb418672c>> (Pdb) p self.field.bound_data(self.data, self.form.initial.get(self.name, self.field.initial)) None (Pdb) p self.data None (Pdb) p self.form.initial.get(self.name, self.field.initial) u'sha1$03d63$4ae1e7f3426c5c8bb4e008dea8d178f88a0c62ed' (Pdb) c
Since this widget has no input fields, and therefore sends no data on POST, I propose modifying it to always return the initial data:
diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py index 9279c52..8246a3b 100644 --- a/django/contrib/auth/forms.py +++ b/django/contrib/auth/forms.py @@ -52,6 +54,13 @@ class ReadOnlyPasswordHashField(forms.Field): kwargs.setdefault("required", False) super(ReadOnlyPasswordHashField, self).__init__(*args, **kwargs) + def bound_data(self, data, initial): + """ + This widget has no fields, so data will always be None, so return + the initial value always. + """ + return initial + class UserCreationForm(forms.ModelForm): """
Change History (3)
comment:1 by , 12 years ago
Easy pickings: | set |
---|---|
Needs tests: | set |
comment:3 by , 12 years ago
Version: | 1.4 → 1.5 |
---|
Note:
See TracTickets
for help on using tickets.
Could you provide an example configuration to reproduce the error with? I can't seem to reproduce this on current Django master.