Opened 3 months ago

Closed 3 months ago

#33731 closed Cleanup/optimization (wontfix)

Updating choices with list methods does not update widget's choices.

Reported by: Stefan-Ionut Tarabuta Owned by: Aman Pandey
Component: Forms Version: 3.2
Severity: Normal Keywords: ChoiceField, choices, form
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Issue

The choices of ChoiceField can be updated by reassigning the choices attribute to a new list of choices. For example, the code below will append 2 more options to the existing choices.

self.fields["my_field"].choices += (("choice1", "Choice 1"), ("choice2", "Choice 2"))

Any operation which involves assignment correctly updates the choices of ChoiceField as well as the underlying widget's choices (what gets rendered in the browser).

However, using other list operations, such as insert, will not update the underlying widget's choices. These operations are useful when precise ordering of choices is desired. For example, the following code will not update the underlying widget's choices (what gets rendered in the browser), but just the form field's choices:

self.fields["my_field"].choices.insert(5, ("choice1", "Choice 1"))

Workaround

The issue can be worked around by performing any assignment on the choices of the ChoiceField, but this is by no means a permanent solution. See the code below which will cause the widget choices to also be updated.

self.fields["my_field"].choices.insert(5, ("choice1", "Choice 1"))  # Insert desired choice. Field is updated, but widget is not.

self.fields["my_field"].choices = self.fields["my_field"].choices  # Force the widget to be updated.

Change History (2)

comment:1 Changed 3 months ago by Aman Pandey

Owner: changed from nobody to Aman Pandey
Status: newassigned

comment:2 Changed 3 months ago by Mariusz Felisiak

Resolution: wontfix
Status: assignedclosed
Summary: Updating choices of ChoiceField does not update the underlying widget's choicesUpdating choices with list methods does not update widget's choices.
Type: BugCleanup/optimization

Thanks for this report, however IMO it's not doable. choices supports many types and we cannot enforce updating widget's choices when built-in methods are called for list or tuple, it's a different layer. I'd recommend to use a callable for choices or to enforce updating widget.choices :

self.fields["my_field"].widget.choices = self.fields["my_field"].choices
Note: See TracTickets for help on using tickets.
Back to Top