Opened 8 years ago

Closed 8 years ago

#20000 closed New feature (fixed)

Allow overriding `label`, `help_text` and `error_messages` for the default fields in `ModelForm`

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


Currently ModelForm requires to completely redefine fields in order to customize user-facing strings such as labels, help_texts and error_messages.

This leads to a lot of boilerplate code to anyone who wants to customize these, but most importantly it's an error prone process. The bigger the ModelForm becomes, the more difficult it is to ensure functional parity between the Model fields and the Form fields for the critical parts such as blank/required, default, validators, etc.

One shouldn't be at risk of completely breaking a form functionality in order to make small cosmetic changes.

It's understood that we have to draw a line somewhere, else we would have field definitions in the Meta, but I believe that line should be drawn at "anything cosmetic" available through Meta overrides, and "anything functional" through fields overrides. I believe the currently provided widgets lie in between the two, so it's almost surprising that it was added as a convenience in a first place instead of the purely cosmetic options.

Change History (15)

comment:2 Changed 8 years ago by Jannis Leidel

Resolution: wontfix
Status: newclosed

This has been previously discussed and wontfixed before. Feel free to raise the issue on the developer list.

comment:3 Changed 8 years ago by Carl Meyer

FWIW, I think this patch would be a positive improvement. It makes common customization cases simpler, and avoids the error-prone alternative of overriding the field entirely and the extra-boilerplate alternative of overriding __init__ and patching fields there. I also think the supplied new customization points are very similar in nature to the existing Meta.widgets, and it's an odd inconsistency to have one but not the others. What argument is there for Meta.widgets that does not apply equally to labels, help texts, and error messages?

In other words, if you decide to bring it up on django-developers, I am +1 for the change.

comment:4 Changed 8 years ago by Carl Meyer

Resolution: wontfix
Status: closednew
Triage Stage: UnreviewedDesign decision needed

comment:5 Changed 8 years ago by Jacob

Triage Stage: Design decision neededAccepted

I agree with Carl.

comment:7 Changed 8 years ago by Łukasz Rekucki

Just for the record, this is a duplicate of #17924.

comment:8 Changed 8 years ago by Tim Graham

I've updated the pull request to merge cleanly and also added the labels, help_texts, and error_messages arguments to the model(form|formset)_factory functions:

comment:9 Changed 8 years ago by Jannis Leidel

I've previously warned that introducing the widgets parameter to the Meta class would open up the possibility "to ask for more". I can't believe Jacob or Carl would become soft in the strict separation of concern between form class and field.

Since I can't provide an alternative as requirement to veto a feature request other than "DON'T DO IT!!1!" I'm forced to change to -0. But I reserve the right to say "I told you so" when a ticket is opened to allow overriding arbitrary field options in the Meta class.

comment:10 Changed 8 years ago by Tim Graham

An alternative which may mitigate the underlying issue of making simple customizations on a ModelForm without having to redeclare the options that are generated by the default form:

FooFormField = MyModel._meta.get_field('foo').formfield() # would probably need a better API

class MyModelForm(ModelForm):
  foo = FooFormField(label='My Foo')

Alternatively, we could recommend doing customization's in __init__, but it doesn't see like the cleanest solution.

comment:11 Changed 8 years ago by loic84

I dislike the FooFormField suggestion, it's very verbose and the intent (override the label) is not immediately obvious.

Also I can't think of any other places in Django where we use such pattern so it feels particularly out of place.

comment:12 Changed 8 years ago by Tim Graham

But it could be a way to override selected options on the the default ModelForm field without having to redeclare all of that field's default options (i.e. for non-cosmetic changes).

comment:13 Changed 8 years ago by Tai Lee

As jezdez points out, this opens up the possibility to "ask for more"... I liked #17924 and I am asking for more :) If we're going to hard code support for a few special cases, why not just support anything in a clean and DRY/elegant/flexible way as was suggested before...

Last edited 8 years ago by Tai Lee (previous) (diff)

comment:14 Changed 8 years ago by Carl Meyer

I think we should move ahead with this ticket as outlined in the description.

I might favor the version in #17924 if we were designing the API from scratch, but the problem with #17924 is that for consistent API it would imply deprecating Meta.widgets, and I just don't think the benefit of a "universal" approach is worth a deprecation cycle for already-existing functionality that's in wide use. (#17924 also carries the minor disadvantage of requiring a lot more commas, quotes, and curly braces for simple customizations.) If we have the common cases covered via direct Meta options, overriding __init__ is still always an option for the uncommon cases.

comment:15 Changed 8 years ago by Tim Graham <timograham@…>

Resolution: fixed
Status: newclosed

In 9e50833e2293aa2734f14f9873abe4f83d03b8c6:

Fixed #20000 -- Allowed ModelForm meta overrides for label, help_text and error_messages

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