Hello, I would like to provide some formatted data to my forms.ChoiceField choices attribute in my Django 5.0 app. I know there were some changes to the “choices” which may be the reason why many options like overriding the “create_option” in my custom Select subclass widget no longer works.
I would like to add my custom data-count attribute to select options but whenever I try to provide
a tuple/dict django converts this to so any “label” data probided to the widget is converted to string I can’t modify the “create_option” in my widget.
Anyone knows about the working (Django >= 5.0) solution? There are many for earlier django versions,
but starting from django 5.0 it does not seem to work.
This is a wagtail page (data fetched from Streamfield… there is no problem so it’s not the case here) but I do this using forms.ChoiceField,
and for the clarification I would like to provide (prepared) choices, for example:
I know I need to proide a simple key-val tupple for forms.ChoiceField(via some function) choices so dediced to subclass Select and add additional extra_data attribute that would be used in a create_option method. Playing with this now, if I get the result I will post here.
Let me know if you know other solution, or maybe I am trying to solve it the wrong way.
This is a common need in my opinion ??
Tried your solution, but maybe there’s a problem with a data that the widget in the form is fed with.
Finally ended with a solution below (probably could be written better)
class CustomSelectWithAttrs(Select):
def __init__(self, *args, **kwargs):
self.extra_data = kwargs.pop("extra_data", [])
super().__init__(*args, **kwargs)
def create_option(
self, name, value, label, selected, index, subindex=None, attrs=None
):
option = super().create_option(
name, value, label, selected, index, subindex=subindex, attrs=attrs
)
if index < len(self.extra_data):
for key, val in self.extra_data[index].items():
option["attrs"][key] = val
return option
def preprocess_choices(choices):
choice_field_choices = [
(choice["value"], choice["label"]) for choice in choices
]
extra_data = [
{k: v for k, v in choice.items() if k not in ["value", "label"]}
for choice in choices
]
return choice_field_choices, extra_data
The logic could probably be moved to the CustomSelectWithAttrs with just providing raw_choices to “choices” widget attribute, but I was getting an error File "/usr/local/lib/python3.12/site-packages/django/forms/widgets.py", line 772, in _choice_has_empty_value value, _ = choice maybe I was doing something wrong.