#15126 closed Bug (fixed)
Misleading error in ModelForm
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Forms | Version: | 1.2 |
Severity: | Normal | Keywords: | modelform fields attributeerror widget subset |
Cc: | bmispelon@… | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Hi,
setting the fields attribute in the Meta-class of a ModelForm to a tuple with only one value specified (without the trailing ',') results in a string. After expiriencing hours of bugtracking i mentioned this fact. The django code in this case doesnt exactly point out, whats causing the problem, because a string as a fields-attribute value also is an iterable object, so it iterates over every single character of this string(handling every charactar as a field) and finaly raises a AttributeError ('ΝοneType' object has no attribute 'widget') when calling the is_valid() method.
It was unnecessarily complicated to recognize the cause for this exception. After this i found, that the python-docs (http://docs.python.org/tutorial/datastructures.html#tuples-and-sequences) also mention this 'ugly' issuse to be fixed by appending a ','.
Perhaps the django-code should help people saving thier time in this case and evaluate if the fields-attribute contains a string or a valid tuple. One solution would be to convert a string to a list or to raise a more meanigful error. Another approach could be a more explicit hint in the ModelForm-Documentation(by mentioning the error it would cause not appending a ',').
Attachments (1)
Change History (9)
comment:1 by , 14 years ago
Triage Stage: | Unreviewed → Accepted |
---|
by , 14 years ago
Attachment: | django15126.testfields.diff added |
---|
comment:2 by , 14 years ago
The above patch tests both fields and exclude for the error. It also includes an extension of the forms-testsuite which tests whether or not the validation is done.
I have two comments with the patch; it would be nice if somebody would reflect on them
- The patch tests specifically for 'str' because I did not want to impair fancy gizmos and create a regression (the docs are not specific on what kind of list fields should be). Testing for string tests for the common mistake without restricting other iterables
- I was not that familiar with testing exceptions thrown by class definitions, so I would appreciate a second opinion on them :-)
comment:3 by , 14 years ago
Has patch: | set |
---|
comment:4 by , 14 years ago
Severity: | → Normal |
---|---|
Type: | → Bug |
comment:5 by , 13 years ago
Easy pickings: | unset |
---|---|
Patch needs improvement: | set |
UI/UX: | unset |
I think the test for str is reasonable.
I think this would be better implemented in the init of ModelFormOptions
also the test should use assertRaises to actually test that the assertion is raised on instantiation, rather than fail after a class is defined, which doesn't actually test your code.
A couple minor points:
- I believe you don't need to test for None, isinstance should suffice
- the error should be that the option should be a iterable of strings, not a single string - list is too specific here
- You don't need to determine the type of the errant value, as you only raise the exception for str type anyway.
comment:6 by , 12 years ago
Cc: | added |
---|---|
Patch needs improvement: | unset |
I fixed up the proposed patch a little and brought it up to date, adressing some of the points made above.
I opted not to put the validation inside the ModelFormOptions.__init__
, so that I would have access to the ModelForm's class in order to provide a more helpful message.
Here's the corresponding pull request: https://github.com/django/django/pull/1000
I added two extra tests (on top of the two new ones for this particular feature):
- Make sure that a
FieldError
is raised when passing an inexisting field toMeta.fields
. - Make sure that no errors are raised when passing an inexisting field to
Meta.exclude
.
comment:7 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
The "single-item tuple" bug is a frequent cause of trouble, especially for newcomers to Python; however, in this case, we are in a position to raise an error.