I think you are looking for ModelMultipleChoiceField. Example:
>>> from django import forms
>>> from django.contrib.auth.models import User
>>>
>>> class MessageForm(forms.Form):
... users = forms.ModelMultipleChoiceField(
... queryset=User.objects,
... widget=forms.CheckboxSelectMultiple,
... required=True)
...
>>> User(username='sdc').save()
>>> User(username='bobby').save()
>>>
>>> print MessageForm(auto_id=False)
<tr><th>Users:</th><td><ul>
<li><label><input type="checkbox" name="users" value="1" />
sdc</label></li>
<li><label><input type="checkbox" name="users" value="2" />
bobby</label></li>
</ul></td></tr>
>>>
For formatting the select list, see today's thread 'Formatting a
Foreign key combo box'.
sdc
You should be looking in cleaned_data, see:
http://docs.djangoproject.com/en/1.0/topics/forms/#processing-the-data-from-a-form
For a ModelMultipleChoiceField, cleaned_data will be a list of model
instances. You shouldn't even have to think about the pk s.
sdc
You don't need to change your form, just use form.cleaned_data in your
view. Same example, a few more lines:
>>> # our form
...
>>> from django import forms
>>> from django.contrib.auth.models import User
>>>
>>> class MessageForm(forms.Form):
... users = forms.ModelMultipleChoiceField(
... queryset=User.objects,
... widget=forms.CheckboxSelectMultiple)
...
>>> # a dump of our template source
...
>>> from django.template.loader import find_template_source
>>> print find_template_source('message.html')[0]
<form action="">
{{ form }}
<input type="submit"/>
</form>
>>>
>>> # our view
...
>>> from django.shortcuts import render_to_response
>>> from django.http import HttpResponseRedirect
>>>
>>> def message(request): # no auto_id just for testing
... if request.method == 'POST':
... form = MessageForm(request.POST, auto_id=False)
... if form.is_valid():
... # normally: do something, then redirect
... print 'users:', form.cleaned_data['users']
... return HttpResponseRedirect('')
... else:
... form = MessageForm(auto_id=False)
... return render_to_response('message.html', { 'form': form })
...
>>> # our urls
...
>>> from django.conf.urls import defaults
>>> urlpatterns = defaults.patterns('', (r'^message', message))
>>>
>>> # example output
...
>>> User(username='sdc').save()
>>> User(username='bobby').save()
>>>
>>> from django.test.client import Client
>>> client = Client()
>>>
>>> # get the form
... print client.get('/message/')
Content-Type: text/html; charset=utf-8
<form action="">
<tr><th>Users:</th><td><ul>
<li><label><input type="checkbox" name="users" value="1" />
sdc</label></li>
<li><label><input type="checkbox" name="users" value="2" />
bobby</label></li>
</ul></td></tr>
<input type="submit"/>
</form>
>>>
>>> # post with some good data
... print client.post('/message/', {'users': [1, 2]})
users: [<User: sdc>, <User: bobby>]
Content-Type: text/html; charset=utf-8
Location: http://testserver/message/
>>>
And yeah, request.POST.get() returns one value, and getlist() returns
a list. See:
http://docs.djangoproject.com/en/1.0/ref/request-response/#querydict-objects
sdc