I have a multivaluefield with a charfield and choicefield. I need to pass choices to the choicefield constructor, however when I try to pass it into my custom multivaluefield I get an error __init__()
got an unexpected keyword argument 'choices'.
I know the rest of the code works because when I remove the choices keyword argument from __init__
and super, the multivaluefield displays correctly but without any choices.
This is how I setup my custom multivaluefield:
class InputAndChoice(object):
def __init__(self, text_val='', choice_val=''):
self.text_val=text_val
self.choice_val=choice_val
class InputAndChoiceWidget(widgets.MultiWidget):
def __init__(self, attrs=None):
widget = (widgets.TextInput(),
widgets.Select()
)
super(InputAndChoiceWidget, self).__init__(widget, attrs=attrs)
def decompress(self,value):
if value:
return [value.text_val, value.choice_val]
return [None, None]
class InputAndChoiceField(forms.MultiValueField):
widget = InputAndChoiceWidget
def __init__(self, required=True, widget=None, label=None, initial=None,
help_text=None, choices=None):
field = (
fields.CharField(),
fields.ChoiceField(choices=choices),
)
super(InputAndChoiceField, self).__init__(fields=field, widget=widget,
label=label, initial=initial, help_text=help_text, choices=choices)
And I call it like so:
input_and_choice = InputAndChoiceField(choices=[(1,'first'),(2,'second')])
So how do I pass the choices to my ChoiceField field?
Edit:
I've tried stefanw's suggestion but still no luck. I've used logging.debug to print out the contents of InputAndChoiceField at the end of the init and self.fields[1].choices contains the correct values as per above however it doesnt display any choices in the browser.
ModelChoiceField
is technically aChoiceField
, but it doesn't actually use any of theChoiceField
's implementations. So, here's how I use it.passing the choices in the widget solved this for me
Have a look at the source of
__init__
offorms.MultiValueField
:So I would overwrite the
__init__
probably like this:You might even want to do
super(MultiValueField, self).__init__(*args, **kwargs)
instead ofsuper(InputAndChoiceField, self).__init__(*args, **kwargs)
because you are setting the fields yourself instead of getting them via parameters.I ran into this exact same problem and solved it like this:
Add a "choices" kwarg to the widget's constructor. Then explicitly call the constructor after the field is created.