#11905 closed (fixed)
modelform_factory returns a broken form when given wrong value for fields
Reported by: | ben | Owned by: | Karen Tracey |
---|---|---|---|
Component: | Forms | Version: | 1.1 |
Severity: | Keywords: | modelform_factory, modelform, fields | |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
modelform_factory is breaking where you ask for an invalid fields option (even if the field exists):
Here's a doctest that demonstrates:
>>> from django.forms.models import modelform_factory, form_for_fields >>> from django.contrib.auth.models import User >>> Form = modelform_factory(User, fields=['id', 'username']) >>> Form.base_fields {'id': None, 'username': <django.forms.fields.CharField object at 0xd4e4ad0>} >>> print Form() ------------------------------------------------------------ Traceback (most recent call last): ... if self.field.label is None: AttributeError: 'NoneType' object has no attribute 'label' Likewise you can specify fields that don't even exist on the model: >>> Form = modelform_factory(User, fields=['no-field', 'username']) >>> Form.base_fields {'no-field': None, 'username': <django.forms.fields.CharField object at 0xd4eec10>} >>> print Form() ------------------------------------------------------------ Traceback (most recent call last): ... if self.field.label is None: AttributeError: 'NoneType' object has no attribute 'label'
This appears to be due to logic in form_for_fields (line 102 in my checkout) in the first case, and fields_for_model (line 170) in the second.
I'd propose some error handling be put in place to give meaningfull exception in either of these cases rather than return a broken form to the user.
I'm happy to submit a patch (I can't do it from here as I'm at work and don't have direct access to django's svn repo) but I can do it from home.
Ben
Attachments (1)
Change History (14)
comment:1 by , 15 years ago
comment:2 by , 15 years ago
I wish this could have a patch as mentionned.
I get the same error on the SVN version and I don't know what is wrong.
http://paste.pocoo.org/show/146130/
Thank you.
comment:3 by , 15 years ago
I have the same error
Caught an exception while rendering: 'NoneType' object has no attribute 'label'
it's occurs on Admin page when i want to use editor to add data to a Model
if comment such models field, and remove it from Admin class for that model, all works fine
techspec = models.ManyToManyField('TechSpec', through = 'ModelTechSpec')
comment:4 by , 15 years ago
Description: | modified (diff) |
---|---|
milestone: | → 1.2 |
Triage Stage: | Unreviewed → Accepted |
comment:5 by , 15 years ago
milestone: | 1.2 → 1.3 |
---|
While better error reporting is always nice, it's not release-critical and can be bumped to 1.3.
comment:6 by , 14 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:7 by , 14 years ago
Owner: | changed from | to
---|---|
Status: | assigned → new |
comment:8 by , 14 years ago
Checking for unknown fields in fields_for_model will break some existing functionality:
- django.contrib.auth uses a custom form for user creation that passes invalid fields (password1 and password2) to fields_for_model.
- If a declarative field is listed in ModelForm._meta.fields (as described here), but is not an actual field of the Model, an error will be raised with this change when it previously succeeded. Current tests (like this one) will fail with this issue.
To test this, I decided to raise a FieldError in fields_for_model when a passed field is not part of the related model. The diff can be found here. I'd be happy to attempt a fix at both the auth and declarative field issues, but I'd like to get some feedback first. Any thoughts?
comment:9 by , 14 years ago
Has patch: | set |
---|
After talking with Karen, I decided to look for a different spot to validate the field list. I ended up modifying ModelFormMetaclass to cross check the fields generated from fields_for_model() against the form's declared fields. fields_for_model returns a mapping of field_name->field, but field will be None if field_name is not found on the specified model. If the missing field name is not found in the declared field list, then the field is considered invalid and will raise a FieldError. With this change, the exception is raised when creating the factory, rather than when rending the form. Patch with tests is attached.
comment:10 by , 14 years ago
Owner: | changed from | to
---|
by , 14 years ago
Attachment: | 11905.diff added |
---|
comment:11 by , 14 years ago
Owner: | changed from | to
---|
comment:12 by , 14 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Sorry screwed up the formatting, try: