6

I have a Form with the following field:

image_choices = [] 
images = forms.ChoiceField(label=_("Images"), choices=image_choices, initial="")

I need to be able to update the value of the 'initial' attribute, after I learn what that value should be. Currently, I have this assignment done within the __init__:

def __init__(self, request, image_choices=image_choices,
             flavor_choices=flavor_choices, args, *kwargs): 
    super(UpdateWorkload, self).__init__(request, args, *kwargs) 
    selected_image = selected_workload['image'] 
    self.fields['images'].initial = selected_image

I do not get any errors, and, when printed, the value is there, but, in the actual form on the screen, I still get my default list, and no specific items are selected, as per self.fields['images'].initial = str(selected_image)

How can I fix that?

Lev Levitsky
  • 63,701
  • 20
  • 147
  • 175
Eugene Goldberg
  • 14,286
  • 20
  • 94
  • 167
  • 1
    Did you tried this: http://stackoverflow.com/a/11400559 ? – mariodev Jan 24 '15 at 15:41
  • 1
    FWIW, dynamic initial values have been a thing since Django 2.0: https://docs.djangoproject.com/en/2.0/ref/forms/api/#dynamic-initial-values – Palisand Nov 04 '20 at 22:08

2 Answers2

5

After all, using this approach:

self.fields['images'].initial = selected_image
self.fields['flavors'].initial = selected_flavor

is working. The only thing I did differently was changing my backend from django restframework to tastypie

Lev Levitsky
  • 63,701
  • 20
  • 147
  • 175
Eugene Goldberg
  • 14,286
  • 20
  • 94
  • 167
0

DANGEROUS SOLUTION:

While the Eugene Goldberg's solution

self.fields['images'].initial = selected_image

does work, it may not be safe in certain scenarios.

The problem with this solution is that you are setting an initial value for a FORM field. This means that this value can be overriden if some other initial values for the FORM are specified in the arguments of the created form (see Colinta's answer), e.g.:

images = forms.ChoiceField(label=_("Images"), choices=image_choices, initial={'images': some_other_image})

Note: Of course, if this behaviour is desirable in your specific app (i.e. sometimes you want to override the initial value defined in __init__). This "dangerous" solution is right for you.

BETTER SOLUTION:

If you want to define an initial value for the field which cannot be overridden by the initial values of the form, you must set the initial value of the FIELD (see Avil Page blog and Django docs)

self.initial['images'] = selected_image

OTHER SOLUTIONS:

For other solutions how to dynamically change initial values, see this answer.

Jakub Holan
  • 303
  • 1
  • 8