Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#30395 closed Cleanup/optimization (fixed)

Document ModelForm specifying field class corresponding to model fields with choices.

Reported by: Quentin Owned by: Tobias Kunze
Component: Documentation Version: dev
Severity: Normal Keywords: ModelForm
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

If a model field has choices, Model.formfield will disregard the form_class keyword argument (plucked from ModelForm.Meta.field_classes), in favor of choices_form_class, which is not set by the ModelForm field generation machinery, and defaults to TypedChoiceField. As a result, the following won't work:

class Language(models.Model):
    LANGUAGES = (
        ('FR', 'French'),
        ('EN', 'English')
    )
    iso = models.CharField(max_length=3, choices=LANGUAGES)

class SloppyIsoField(CharField):
    """Choice field that strips and uppercases language codes"""

    def to_python(self, value):
        value = super().to_python(value)
        return value.strip().upper()

class LanguageForm(forms.ModelForm):
    class Meta:
        fields = ('iso',)
        field_classes = {
            'iso': SloppyIsoField
        }

Granted, this is a bit contrived, but it might be worth mentioning the caveat in the docs. Or maybe allow a Meta.choices_field_classes? If this is relevant I'd happily contribute.

Change History (6)

comment:1 by Carlton Gibson, 5 years ago

Component: FormsDocumentation
Triage Stage: UnreviewedAccepted
Type: New featureCleanup/optimization
Version: 2.2master

Hi Quentin,

Thanks for the report.

Essentially, you've hit the limit of what's worth doing with Meta options vs just declaring the form fields by hand. There comes a point when the meta API just isn't any simpler...
— I don't think there'd be any appetite for adding another meta option for this. "Just declare the iso = SloppyIsoField(...) directly" will be the advise. (Or use a custom model field class specifying it's choices_form_class in formfield...)

I guess an addition to Overriding the default fields section of the ModelForms docs would be OK, if you can come up with a suitable addition.

Looking from the paragraph starting Finally, if you want complete control over of a field .... A sentence or two added there may be appropriate.
(Will accept on that basis.)

comment:2 by Carlton Gibson, 5 years ago

Summary: ModelForm: allow to declaratively specify field classes corresponding to model fields with choicesDocument ModelForm specifying field class corresponding to model fields with choices.

comment:3 by Tobias Kunze, 5 years ago

Owner: changed from nobody to Tobias Kunze
Status: newassigned

comment:4 by Tobias Kunze, 5 years ago

Has patch: set

comment:5 by Mariusz Felisiak <felisiak.mariusz@…>, 5 years ago

Resolution: fixed
Status: assignedclosed

In a309821:

Fixed #30395 -- Doc'd a limitation of ModelForm.Meta.widgets.

comment:6 by Mariusz Felisiak <felisiak.mariusz@…>, 5 years ago

In 85b6984:

[2.2.x] Fixed #30395 -- Doc'd a limitation of ModelForm.Meta.widgets.

Backport of a309821c973cf3bcfe817bb71163fcccc461cec1 from master

Note: See TracTickets for help on using tickets.
Back to Top