#35542 closed Cleanup/optimization (needsinfo)
BoundField's label and help_text and renderer should be properties not class members
Reported by: | Christophe Henry | Owned by: | Christophe Henry |
---|---|---|---|
Component: | Forms | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Christophe Henry | Triage Stage: | Unreviewed |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
BoundField
exposes label help_text and renderer, all of them are copies of underlying members of Field
and Form
.
This is a bit misleanding since you can modify Field
s member in Form
's __init__
like documented here but any modification of help_text
, label
or renderer
after super().__init__
won't be reflected on the bound which can leand to incomprehensible behavior in templates
Change History (2)
follow-up: 2 comment:1 by , 8 days ago
Resolution: | → needsinfo |
---|---|
Status: | assigned → closed |
Type: | Uncategorized → Cleanup/optimization |
Version: | 5.0 → dev |
comment:2 by , 2 days ago
Replying to Natalia Bidart:
Hello Natalia!
Well the documentation I linked features this as the first example:
class FooMultipleChoiceForm(forms.Form): foo_select = forms.ModelMultipleChoiceField(queryset=None) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields["foo_select"].queryset = ...
The same way, you can do this, for instance:
class FooMultipleChoiceForm(forms.Form): foo_select = forms.CharField() def __init__(self, user: User, *args, **kwargs): super().__init__(*args, **kwargs) self.fields["foo_select"].help_text = f"Indicate {user.first_name}'s pet name"
But if you do this, you won't get the result you expect when rendering form with {{ form }}
since what will be rendered is self["foo_select"].help_text.
(the associated BoundField
) and not self.fields["foo_select"].help_text
. In order for the help text to correctly be rendered, you need to write:
class FooMultipleChoiceForm(forms.Form): foo_select = forms.CharField() def __init__(self, user: User, *args, **kwargs): super().__init__(*args, **kwargs) # Not self.field self["foo_select"].help_text = f"Indicate {user.first_name}'s pet name"
This is confusing and is inconsistant with the queryset
example of the documentation for anyone who's not very familiar with Django's Form
API and looks very much like a bug.
My proposed solution does not introduce any breaking changes and can even be easily reverted to its original behavior with the patch I also proposed for #35192.
Hello again Christophe Henry! Thank you for your report.
We would need more information to understand your use case. The documentation you linked about "Fields which handle relationships" refers to redefining a field's queryset, not the label/help_text/renderer/etc.
With the information provided so far, I cannot determine whether this is a very specific issue arising from a niche use case or something that applies to the broader ecosystem. Django is a framework designed to provide robust and reliable solutions for common scenarios. Therefore, before accepting any changes to well-established and mature code, it is crucial to demonstrate clear benefits from the proposed modification and ensure there are no risks of breaking existing functionality.
Specifically, we would need a small Django test project or a failing test case that shows the code path or use case that needs fixing. I'll close as
needsinfo
in the meantime.