ChatGPT解决这个技术问题 Extra ChatGPT

Setting the selected value on a Django forms.ChoiceField

Here is the field declaration in a form:

max_number = forms.ChoiceField(widget = forms.Select(), 
    choices = ([('1','1'), ('2','2'),('3','3'), ]), initial='3', required = True,)

I would like to set the initial value to be 3 and this doesn't seem to work. I have played about with the param, quotes/no quotes, etc... but no change.

Could anyone give me a definitive answer if it is possible? And/or the necessary tweak in my code snippet?

I am using Django 1.0

I've been wondering the same thing. "initial" doesn't seam to work with choices in the latest trunk version as well.

T
Tom

Try setting the initial value when you instantiate the form:

form = MyForm(initial={'max_number': '3'})

Is '3' corresponding to the first value of the tuple or the second?
the tuples represent (value, label) pairs for the options and you want to specify the initial value - so the '3' refers to the first item.
c
colinta

This doesn't touch on the immediate question at hand, but this Q/A comes up for searches related to trying to assign the selected value to a ChoiceField.

If you have already called super().__init__ in your Form class, you should update the form.initial dictionary, not the field.initial property. If you study form.initial (e.g. print self.initial after the call to super().__init__), it will contain values for all the fields. Having a value of None in that dict will override the field.initial value.

e.g.

class MyForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        # assign a (computed, I assume) default value to the choice field
        self.initial['choices_field_name'] = 'default value'
        # you should NOT do this:
        self.fields['choices_field_name'].initial = 'default value'

if you do not understand this answer, read this django form gotchas
I am not sure if it is because this answer is so old that this no longer works, but I am unable to make this solution work. I have tried every combination of the above and still I get no love. I have asked this question again here: stackoverflow.com/questions/52191096/… If the answer is still the same, please let me know what is wrong with my code. Thank you!
B
Burton Williams

You can also do the following. in your form class def:

max_number = forms.ChoiceField(widget = forms.Select(), 
                 choices = ([('1','1'), ('2','2'),('3','3'), ]), initial='3', required = True,)

then when calling the form in your view you can dynamically set both initial choices and choice list.

yourFormInstance = YourFormClass()

yourFormInstance.fields['max_number'].choices = [(1,1),(2,2),(3,3)]
yourFormInstance.fields['max_number'].initial = [1]

Note: the initial values has to be a list and the choices has to be 2-tuples, in my example above i have a list of 2-tuples. Hope this helps.


Perhaps worth noting that the value of initial refers to the key of the item to be selected, not its index. Took me a couple of tries to work this out!
D
Dave

I ran into this problem as well, and figured out that the problem is in the browser. When you refresh the browser is re-populating the form with the same values as before, ignoring the checked field. If you view source, you'll see the checked value is correct. Or put your cursor in your browser's URL field and hit enter. That will re-load the form from scratch.


just fyi, This still happen in FF6. Pressing the refresh button is not enough. But in google chrome refresh button is enough, no need to go to address bar
I think it will always happen in Firefox; it's intended behaviour.
o
orlade

Both Tom and Burton's answers work for me eventually, but I had a little trouble figuring out how to apply them to a ModelChoiceField.

The only trick to it is that the choices are stored as tuples of (<model's ID>, <model's unicode repr>), so if you want to set the initial model selection, you pass the model's ID as the initial value, not the object itself or it's name or anything else. Then it's as simple as:

form = EmployeeForm(initial={'manager': manager_employee_id})

Alternatively the initial argument can be ignored in place of an extra line with:

form.fields['manager'].initial = manager_employee_id

Your second line of code works flawlessly in one of those rare cases where you need to set a form's initial value after a GET request and set it from within a view.
I confirm, that's the only way to make it work using ModelChoiceField (Django 2.1, sadly. Maybe in newer ones it works better).
佚名

Dave - any luck finding a solution to the browser problem? Is there a way to force a refresh?

As for the original problem, try the following when initializing the form:

def __init__(self, *args, **kwargs):
  super(MyForm, self).__init__(*args, **kwargs)   
  self.base_fields['MyChoiceField'].initial = initial_value

This doesn't look nicely. Quoted from django 1.3, forms.py:93: Instances should always modify self.fields; they should not modify self.base_fields.
A
Andrew Wilkinson

To be sure I need to see how you're rendering the form. The initial value is only used in a unbound form, if it's bound and a value for that field is not included nothing will be selected.