twampss twampss - 1 year ago 657
Python Question

Django Multiple Choice Field / Checkbox Select Multiple

I have a Django application and want to display multiple choice checkboxes in a user's profile. They will then be able to select multiple items.

This is a simplified version of my

from profiles.choices import SAMPLE_CHOICES

class Profile(models.Model):
user = models.ForeignKey(User, unique=True, verbose_name_('user'))
choice_field = models.CharField(_('Some choices...'), choices=SAMPLE_CHOICES, max_length=50)

And my form class:

class ProfileForm(forms.ModelForm):
choice_field = forms.MultipleChoiceField(choices=SAMPLE_CHOICES, widget=forms.CheckboxSelectMultiple)

class Meta:
model = Profile

And my

if request.method == "POST":
profile_form = form_class(request.POST, instance=profile)
if profile_form.is_valid():
return render_to_response(template_name, {"profile_form": profile_form,}, context_instance=RequestContext(request))

I can see that the POST is only sending one value:

choice_field u'choice_three'

And the local vars params is sending a list:

[u'choice_one', u'choice_two', u'choice_three']

All of the form fields display correct, but when I submit a POST, I get an error

Error binding parameter 7 - probably unsupported type.

Do I need to process the multiple choice field further in the view? Is the model field type correct? Any help or references would be greatly appreciated.

Answer Source

The profile choices need to be setup as a ManyToManyField for this to work correctly.

So... your model should be like this:

class Choices(models.Model):
  description = models.CharField(max_length=300)

class Profile(models.Model):
  user = models.ForeignKey(User, blank=True, unique=True, verbose_name='user')
  choices = models.ManyToManyField(Choices)

Then, sync the database and load up Choices with the various options you want available.

Now, the ModelForm will build itself...

class ProfileForm(forms.ModelForm):
    model = Profile
    exclude = ['user']

And finally, the view:

if request.method=='POST':
  form = ProfileForm(request.POST)
  if form.is_valid():
    profile =
    profile.user = request.user
  form = ProfileForm()

return render_to_response(template_name, {"profile_form": form}, context_instance=RequestContext(request))

It should be mentioned that you could setup a profile in a couple different ways, including inheritance. That said, this should work for you as well.

Good luck.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download