Passing hidden foreign key to form as initial value

6,851 views
Skip to first unread message

phoebebright

unread,
Mar 31, 2010, 9:20:48 AM3/31/10
to Django users
Displayed fields resolve as expected, hidden fields cause errors.

This works:

in the model
CourseBook has a foreign key to Course

In the view:

course = Course.objects.get(pk=whatever)
form = CouseBook(initial = {'course': course})


in the Form:

class CourseBook(ModelForm):
class Meta:
model = CourseBooking


The web page now displays a picklist of courses with the initial value
highlighted. I can now do a form.save() no problem.

However, if I make the course a hidden field, which is what I want.

class CourseBook(ModelForm):
course = forms.CharField(widget=forms.HiddenInput())

class Meta:
model = CourseBooking

then when I come to save() I get a ValueError, unable to assign "My
course" etc. as it tries to put the name of the course into the
foreign key instead of a course instance.

I can work around this putting a save method on the form, but it seems
to me django should resolve this for me????

Brandon Taylor

unread,
Mar 31, 2010, 11:02:28 AM3/31/10
to Django users
Hi there,

Instead of using the course object in your initial data, which will
pass in the __unicode__ representation of the object, pass in the id:

form = CouseBook(initial = {'course': course.id})

That should get you the numeric id, but you'll also need to override
your save method to get the course object to assign when you save your
CourseBook form, as you can't assign an integer (coming from your
hidden form field) to the value of a ForeignKey field on a model.

HTH,
Brandon

phoebebright

unread,
Mar 31, 2010, 11:15:59 AM3/31/10
to Django users
Brandon, Thanks for your suggestion.
I tried passing it an ID, but as you say, I also have to override the
save. What I don't understand is why it does it fine if the form
includes the foreign key in a popup? They are both passing back
integers after all.

Also failed to get the save method working, tried to pass in the
course instance, but it still ends up trying to save with the id of
the course. Is it not using cleaned_data?


def save(self, course=False, force_insert=False,
force_update=False, commit=True):
if course:
self.cleaned_data['course'] = course
return super(CourseBook, self).save(commit=commit)


Any suggestions welcome as I've spent the whole afternoon on this - I
won't go through the many other workarounds that havn't worked!

Phoebe.

phoebebright

unread,
Mar 31, 2010, 3:06:41 PM3/31/10
to Django users
Final approach:
in the forms.py excluded the courses foreign key field
in models.py made courses blank and nullable
didn't pass any initial values to the form
in the view, saved the form like this:
item = Courses.objects.get(pk=whatever)
obj = form.save(commit=False)
obj.course = item
obj.save()

This doesn't feel very tidy to me, I think the form should have the
hidden values, but it works!

Nuno Maltez

unread,
Apr 1, 2010, 9:08:44 AM4/1/10
to django...@googlegroups.com
What about:

class CourseBook(ModelForm):
course = ModelChoiceField(queryset=Course.objects.all(),
widget=HiddenInput())

class Meta:
model = CourseBooking

and in your view:

form = CourseBook(initial = {'course': course.pk})


Nuno

> --
> You received this message because you are subscribed to the Google Groups "Django users" group.
> To post to this group, send email to django...@googlegroups.com.
> To unsubscribe from this group, send email to django-users...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
>
>

phoebebright

unread,
Apr 1, 2010, 1:49:58 PM4/1/10
to Django users
That's one option, the problem is changing the course value returned
from the form into a course object so that the form will validate.
This turned out to be a surprising amount of trouble (because you have
to do it before validation), hence reason for doing simpler work
around.

On Apr 1, 2:08 pm, Nuno Maltez <nuno.li...@gmail.com> wrote:
> What about:
>
> class CourseBook(ModelForm):
>    course = ModelChoiceField(queryset=Course.objects.all(),
> widget=HiddenInput())
>
>    class Meta:
>        model = CourseBooking
>
> and in your view:
>
> form = CourseBook(initial = {'course': course.pk})
>
> Nuno
>

> On Wed, Mar 31, 2010 at 8:06 PM, phoebebright <phoebebright...@gmail.com> wrote:
> > Final approach:
> > in the forms.py excluded the courses foreign key field
> > in models.py made courses blank and nullable
> > didn't pass any initial values to the form
> > in the view, saved the form like this:
> >            item = Courses.objects.get(pk=whatever)
> >            obj = form.save(commit=False)
> >            obj.course = item
> >            obj.save()
>
> > This doesn't feel very tidy to me, I think the form should have the

> >hiddenvalues, but it works!

> >> >hiddenform field) to the value of a ForeignKey field on a model.


>
> >> > HTH,
> >> > Brandon
>
> >> > On Mar 31, 8:20 am, phoebebright <phoebebright...@gmail.com> wrote:
>

> >> > > Displayed fields resolve as expected,hiddenfields cause errors.


>
> >> > > This works:
>
> >> > > in the model
> >> > > CourseBook has a foreign key to Course
>
> >> > > In the view:
>
> >> > > course = Course.objects.get(pk=whatever)
> >> > > form = CouseBook(initial = {'course': course})
>
> >> > > in the Form:
>
> >> > > class CourseBook(ModelForm):
> >> > >     class Meta:
> >> > >         model = CourseBooking
>
> >> > > The web page now displays a picklist of courses with the initial value
> >> > > highlighted.  I can now do a form.save() no problem.
>

> >> > > However, if I make the course ahiddenfield, which is what I want.

Nuno Maltez

unread,
Apr 1, 2010, 2:01:54 PM4/1/10
to django...@googlegroups.com
I think the form I sent, with ModelChoiceField, will validate with the
returned values without any further code. Or am I missing something
obvious?

phoebebright

unread,
Apr 2, 2010, 5:22:19 AM4/2/10
to Django users
OK - Now I've actually read your code properly! Yes that is a
brilliant solution!

Thanks.

Phoebe.


On Apr 1, 7:01 pm, Nuno Maltez <nuno.li...@gmail.com> wrote:
> I think the form I sent, with ModelChoiceField, will validate with the
> returned values without any further code. Or am I missing something
> obvious?
>

Michel Z. Santello

unread,
May 6, 2016, 12:20:03 PM5/6/16
to Django users
Can somebody explain why did occurs with widget=forms.HiddenInput ?

Thank's.

Peter of the Norse

unread,
Jun 7, 2016, 1:41:29 AM6/7/16
to django...@googlegroups.com
Because CharField is designed for text data. So the form field turns the course into a string and tries to save a string to the model. That doesn’t work.

The only built-in field designed to work with foreign keys is ModelChoiceField. You could update it so that it doesn’t run a queryset and uses HiddenInput.

The other option is to remove course from the ModelForm and instead use course_id with IntergerField. This would be the fastest and not hit the database as often. I recommend doing this. Or, if this uses an existing object, not have anything there. Things left out of the ModelForm don’t get updated when you save the form.
> --
> You received this message because you are subscribed to the Google Groups "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
> To post to this group, send email to django...@googlegroups.com.
> Visit this group at https://groups.google.com/group/django-users.
> To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/3628bd01-59b2-4291-94f5-072d6de9f7c7%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Peter of the Norse
Rahm...@Radio1190.org



Reply all
Reply to author
Forward
0 new messages