#20999 closed New feature (fixed)
Cannot specify form_class that isn't subclass of TypedChoiceField for field with choices
| Reported by: | Carl Meyer | Owned by: | nobody |
|---|---|---|---|
| Component: | Forms | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Ready for checkin | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
In Field.formfield(), if self.choices is set, Django overrides any supplied form_class with TypedChoiceField unless the given form_class is a subclass of TypedChoiceField. This is unnecessarily restrictive (as explicit type checks usually are), and is particularly problematic when working with a field that takes multiple values (such as a Postgres array field), where TypedMultipleChoiceField would be the appropriate form field class, because TypedMultipleChoiceField is not a subclass of TypedChoiceField.
Prior to the fix for #18162, Django was even more restrictive; a custom form_class was not respected at all when choices were set.
I think the wrong fix for #18162 was chosen. The original patch provided by rafallo there would have respected a new keyword argument to formfield(), form_class_for_choices. This provides full flexibility, and is conceptually more correct; since a totally different form field is generally needed for the same db field when there are choices, a separate keyword argument to control this form field is appropriate. I propose that we switch to rafallo's fix (though I prefer the slightly shorter name choices_form_class).
Unfortunately since the subclass check was committed and released in the 1.6 betas, we probably still have to maintain compatibility with people passing a subclass of TypedChoiceField as form_class and expecting it to be used when choices are set.
Change History (8)
comment:1 by , 12 years ago
| Has patch: | set |
|---|
comment:2 by , 12 years ago
| Triage Stage: | Unreviewed → Ready for checkin |
|---|
I think this is a better solution to the problem.
comment:3 by , 12 years ago
I wouldn't consider beta releases as stable APIs, so I would not have considered the change as backwards incompatible. So +1 for the new keyword, but I would have removed at least the issubclass check. There is a missing versionchanged in the docs.
comment:4 by , 12 years ago
If this patch is not backported to 1.6, then the subclass check will be released in 1.6 final, and not supporting it in 1.7 would be a backwards-compatibility issue.
If others are ok with it, I'm happy to backport this fix to 1.6 now and remove the subclass check entirely; that could potentially cause an issue for someone upgrading from a 1.6 beta to 1.6 rc/final, but maybe that's not a concern.
comment:5 by , 12 years ago
I'm in favour of backporting. It's not exactly a new feature, rather a fix to an existing one. Last chance before the RC!
comment:7 by , 12 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
Pull request at https://github.com/django/django/pull/1530