70

I'm using something like this:

field1 = forms.ModelChoiceField(queryset=...)

How can I make my form show the a value as selected?

Dominic Rodger
  • 97,747
  • 36
  • 197
  • 212
Asinox
  • 6,747
  • 14
  • 61
  • 89

7 Answers7

106

If you want to set the default initial value you should be defining initial like other form fields except you set it to the id instead.

Say you've got field1 like this:

class YourForm(forms.Form):
    field1 = forms.ModelChoiceField(queryset = MyModel.objects.all() )

then you need to set initial when you create your form like this:

form = YourForm(initial = {'field1': instance_of_mymodel.pk })

rather than:

form = YourForm(initial = {'field1': instance_of_mymodel })

I'm also assuming you've defined __unicode__ for your models so this displays correctly.

Chris
  • 11,780
  • 13
  • 48
  • 70
Michael Cheng
  • 9,644
  • 6
  • 46
  • 48
  • Don't know what the version was at the time of this writing, but this question is now a bit out-dated. In Django 1.5, as of writing, both of these methods would work. – JcKelley Jun 26 '13 at 14:57
  • 1
    any idea why I get `__init__() got an unexpected keyword argument field1` – dashesy Jan 14 '15 at 20:10
30

You can just use

 field1 = forms.ModelChoiceField(queryset=..., initial=0) 

to make the first value selected etc. It's more generic way, then the other answer.

Pavel Shvedov
  • 1,284
  • 11
  • 8
  • 2
    What version of Django does this work for? It doesn't seem to work for me in version 1.8. – BudgieInWA Oct 20 '15 at 06:21
  • I have verified from the [source code](https://github.com/django/django/blob/1.8.11/django/forms/models.py#L1127-L1130) and test it out myself that this is working for `django>=1.8`. I believe this should work for all version including `>=1.4` – Yeo Mar 29 '16 at 03:33
  • 1
    @Raffi yes, the [link in my comment above](https://github.com/django/django/blob/1.8.11/django/forms/models.py#L1127-L1130) is pointing to the parameter of `ModelChoiceField.__init__(..., initial,...)` for Django=1.8.11. – Yeo May 21 '18 at 11:37
11

The times they have changed:

The default initial value can now be set by defining initial like other form fields except you set it to the id instead.

Now this will suffice:

form = YourForm(initial = {'field1': instance_of_mymodel })

Though both still work.

George Stocker
  • 57,289
  • 29
  • 176
  • 237
Williams
  • 4,044
  • 1
  • 37
  • 53
  • 9
    Please specify what version of Django you're running now that the "times have changed." Changed for some out there might be upgrade to 1.2... – scoopseven Jan 24 '13 at 19:18
5

The code

form = YourForm(initial = {'field1': instance_of_mymodel.pk })

and

form = YourForm(initial = {'field1': instance_of_mymodel })

or initial field directly following:

field1 = forms.ModelChoiceField(queryset=..., initial=0) 

All work.

The first two ways will override the final way.

Jonnus
  • 2,988
  • 2
  • 24
  • 33
3
field1 = forms.ModelChoiceField(queryset=Model.objects.all(), empty_label="Selected value")

It's as simple as that....!

Faizan Mustafa
  • 371
  • 5
  • 19
0

Just want to add this answer after stumbling on this question. I know it works on Django 3.2, at least. If you have some calculated value in the __init__ method, you can do this to set the initial value at instantiation as well:

def __init__(self, value, *args, **kwargs):
    # super call, etc.
    self.do_something(value)
    self.fields['field'].initial = value

If the form does multiple things with value, it's a bit more DRY to pass it only once instead of redundantly with the initial kwarg in instantiation.

Spenser Black
  • 317
  • 3
  • 8
-1

You could do this as well:

form = YourForm(initial = {'field1': pk })

if you are parsing your primary key through a query string or via an ajax call no need for an instance, the query set has already handled that for your drop down, the pk indexes the state you want