Setting initial Django form field value in the __init__ method

52,562

Solution 1

I had that exact same problem and I solved it doing this:

def __init__(self, *args, **kwargs):
    instance = kwargs.get('instance', None)

    kwargs.update(initial={
        # 'field': 'value'
        'km_partida': '1020'
    })

    super(ViagemForm, self).__init__(*args, **kwargs)

    # all other stuff

Solution 2

Try this way:

super(ViagemForm, self).__init__(*args, **kwargs)

if field_value:
    #self.initial[field_name] = field_value
    self.fields[field_name].initial = field_value

Solution 3

I want to mention, although this might not solve your problem, that an 'initial' dict kwarg sent to a form appears to get preference over field['field_name'].initial.

class MyView(View):
    form = MyForm(initial={'my_field': 'first_value'})

class MyForm(Form):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['my_field'].initial = 'second_value'

my_field rendered will have initial set to 'first_value'.

Some options (among others) might be:

Determine second_value in the view before initializing the form:

class MyView(View):
    # determine second_value here
    form = MyForm(initial={'my_field': 'second_value'})

replace first_value with second_value in initial before calling super():

class MyForm(Form):
    def __init__(self, *args, **kwargs):
        # determine second_value here
        if kwargs.get('initial', None):
            kwargs['initial']['my_field'] = 'second_value'
        super().__init__(*args, **kwargs)

Make sure 'first_value' isn't in kwargs['initial'] before calling super():

class MyForm(Form):
    def __init__(self, *args, **kwargs):
        if kwargs.get('initial', None):
            if kwargs['initial']['my_field']
                del(kwargs['initial']['my_field']
        super().__init__(*args, **kwargs)
        # determine second_value here
        self.fields['my_field'].initial = 'second_value'
Share:
52,562
Steve Sawyer
Author by

Steve Sawyer

Programming for too long to even try to count. Don't like the software business, and believe in doing things right as close to 100% of the time as possible, so I don't usually get along with other programmers (co-workers) very well. I also enjoy biking, playing guitar and woodworking.

Updated on July 12, 2022

Comments

  • Steve Sawyer
    Steve Sawyer almost 2 years

    Django 1.6

    I have a working block of code in a Django form class as shown below. The data set from which I'm building the form field list can include an initial value for any of the fields, and I'm having no success in setting that initial value in the form. The if field_value: block below does indeed populate the initial form dictionary attribute, but the initial value is not being displayed. Note that (in case you are wondering) the .initial attribute does not exist until after the super() call.

    Can this be done?

    If so, what I'm not doing right to make this work?

    Thanks!

    def __init__(self, *args, **kwargs):
        id = kwargs.pop('values_id', 0)
        super(LaunchForm, self).__init__(*args, **kwargs)
        # Lotsa code here that uses the id value
        # to execute a query and build the form
        # fields and their attributes from the 
        # result set
    
        if field_value:
            self.initial[field_name] = field_value
    
  • Steve Sawyer
    Steve Sawyer over 10 years
    @ndpu - thanks, but that too doesn't work - the field object exists, and it has a data attribute of "initial" that is indeed set to the initial value, but it's not showing up on the form. @karthikr - the code that establishes the form fields is executed AFTER the super() call, and it isn't until this code executes that I know what the initial values(s) should be. I also tried `self.initial.update({field_name: field_value})' but that also leaves the field blank on the page. I also tried to set the initial field argument as part of the field definition - no success with that approach.
  • karthikr
    karthikr over 10 years
    Well. i use the exact same code as I have shown in the answer, and it works for me.
  • Steve Sawyer
    Steve Sawyer over 10 years
    @karthikr - My guess is that yours is working because you're calling super() after setting the property. Things got even more interesting in playing with this on Friday - not only can I verify that the initial value exists, it's also a required field, and the value's presence is causing the form to pass is_valid() in the view's post() method! So, I'm getting the worst of everything - the value is there and is validated, but won't display on the form!!
  • Steve Sawyer
    Steve Sawyer over 10 years
    I'm no closer to getting this working the way I need it to do so, but I'm making a couple of discoveries, and the failure may not lie with how I'm populating the initial value, but with the behavior of the field type (or my understanding of that behavior). I'm going to post a new topic that gets into this aspect of the issue. Thanks for all your input.
  • biodiv
    biodiv about 8 years
    you have to init the form with super first to make self.fields available
  • Julio Marins
    Julio Marins almost 7 years
    I did super first and then did the changes and it sets the choice field value to the first choice available. Not working for me