Prepopulate Django (non-Model) Form

DjangoDjango Forms

Django Problem Overview


I'm trying to prepopulate the data in my django form based on some information, but NOT using ModelForm, so I can't just set the instance.

This seems like it should be really easy, but for some reason I can't find any documentation telling me how to do this. This is my form:

class MyForm(forms.Form):
  charfield1 = forms.CharField(max_length=3)
  charfield2 = forms.CharField(max_length=3)
  choicefield = forms.ModelChoiceField(MyModel.objects.all())

I tried just doing:

form = MyForm()
form.charfield1 = "foo"
form.charfield2 = "bar"
# a model choice field
form.choicefield = MyModel.objects.get(id=3)

which does not work.

Django Solutions


Solution 1 - Django

Try:

form = MyForm({'charfield1': 'foo', 'charfield2': 'bar'})

The constructor of Form objects can take a dictionary of field values. This creates a bound form, which can be used to validate the data and render the form as HTML with the data displayed. See the forms API documentation for more details.

Edit:

For the sake of completeness, if you do not want to bind the form, and you just want to declare initial values for some fields, you can use the following instead:

form = MyForm(initial={'charfield1': 'foo', 'charfield2': 'bar'})

See the documentation of initial values for details.

Solution 2 - Django

There are two ways of populating a Django form.

The first is to pass a dictionary as the first argument when you instantiate it (or pass it as the data kwarg, which is the same thing). This is what you do when you want to use POST data to populate and validate the form.

data_dict = {'charfield1': 'data1', 'charfield2': 'data2', 'choicefield': 3}
form = MyForm(data_dict)

However, this will trigger validation on the form, so only works if you are actually passing in valid and complete data to begin with - otherwise you will start off with errors.

The other way to populate a form is to use the initial parameter (documented here). This gives initial values for the form fields, but does not trigger validation. It's therefore suitable if you're not filling in all values, for example.

form = MyForm(initial=data_dict)

To populate a choicefield via initial, use the pk value.

Solution 3 - Django

You can use model_to_dict() to convert an instance to a dictionary, and then populate a form with that. Something like this should work:

from django.forms.models import model_to_dict
...
my_obj = MyModel.objects.get(abc=123)
form = MyForm(initial=model_to_dict(my_obj))

Note: I'm using django version 1.3

Solution 4 - Django

For what it's worth, the FormView class-based view way to do this would be to override the FormView's get_initial function. get_initial returns the initial keyword arguments used by get_form_kwargs to instantiate the form.

Docs:

  • for get_initial, here,
  • for get_form_kwargs, here.

Sample code:

from django.views.generic.edit import FormView

class MyFormView(FormView):

    def get_initial(self):
        initial = super(MyFormView, self).get_initial()
        # update initial field defaults with custom set default values:
        initial.update({'charfield1': 'foo', 'charfield2': 'bar'})
        return initial

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCoryView Question on Stackoverflow
Solution 1 - DjangoAyman HouriehView Answer on Stackoverflow
Solution 2 - DjangoDaniel RosemanView Answer on Stackoverflow
Solution 3 - DjangoAndrew CalderView Answer on Stackoverflow
Solution 4 - DjangoJoseph Victor ZammitView Answer on Stackoverflow