Seeking Example of MultipleChoiceField Example with dynamic Choices

1,049 views
Skip to first unread message

Bobby Roberts

unread,
May 17, 2009, 10:10:01 AM5/17/09
to Django users
Hi. I'm needing to learn how to dynamically pull data out of the
database and pass it as a CHOICES argument in my form. I want to pull
a recordset of options, dump it into the choices and pass it to the
form etc. Can someone out there lend me a hand? I'd like the options
on the form to be checkboxes.

lokeshm...@gmail.com

unread,
May 17, 2009, 12:16:42 PM5/17/09
to Django users
Hi,

p=Country.objects.all() -----> capturing all the records from
Country table
def country_filler(self): -----> function to generate a country
list which we are going to fetch from the records
incr = 0
for i in p:
self[incr] = i.country
incr = incr+1
return self.items()

country = forms.CharField(label="cnty",
widget=forms.CheckboxSelectMultiple(choices=country_filler
(country_list)))

Hope the above lines will help you.

Regards,
Lokesh

Alex Gaynor

unread,
May 17, 2009, 12:18:55 PM5/17/09
to django...@googlegroups.com
If you're using choices you really should use a ChoiceField as it will validate that the selections is one of the desired choices, which won't be validated with a CharField.

Alex

--
"I disapprove of what you say, but I will defend to the death your right to say it." --Voltaire
"The people's good is the highest law."--Cicero

Lokesh

unread,
May 17, 2009, 12:24:45 PM5/17/09
to Django users
Hi Alex,

Then I can go ahead with required=false attribute to avoid form
validation and validation should be taken care by program.
Correct me if I am wrong.

Regards,
Lokesh

Alex Gaynor

unread,
May 17, 2009, 12:26:14 PM5/17/09
to django...@googlegroups.com
Yes, if you don't want Django to automatically validate it is a valid choice you can just do it is a CharField and do it yourself.

Bobby Roberts

unread,
May 17, 2009, 12:41:28 PM5/17/09
to Django users
> p=Country.objects.all()   -----> capturing all the records from
> Country table
> def country_filler(self):    -----> function  to generate a country
> list which we are going to fetch from the records
>     incr = 0
>     for i in p:
>        self[incr] = i.country
>        incr = incr+1
>     return self.items()
>
> country = forms.CharField(label="cnty",
> widget=forms.CheckboxSelectMultiple(choices=country_filler
> (country_list)))
>

ok here's what i have based on that example:


from django import forms

# pull a recordset of the users
userdata = auth_user.objects.all()

def user_filler(self):
counter=0
for i in userdata:
self[counter] = i.username
counter=counter+1
return self.items()

#used to post messages to other users
class FrmMessage (forms.Form):
posted_to = forms.ChoiceField
(required=True,widget=forms.CheckboxSelectMultiple(attrs=
{'class':'optchecklist'},choices=user_filler(userdata)))
message = forms.CharField (max_length=300, required=True,
widget=forms.Textarea(attrs={'class':'smallblob'}))



two questions.

1. first, is this right?
2. secondly, how can i pass the auth_user.id and the right
auth_user.username back to the form? This example seems to just send
one back. I need the value of the checkboxes to be the id and the
visible text to be the firstname + lastname

The idea is to let them choose to whom they want to send a quick
message

Lokesh

unread,
May 17, 2009, 1:14:11 PM5/17/09
to Django users
Hi,

Try this below code. I guess this will solve your purpose

# pull a recordset of the users
userdata = auth_user.objects.all()

def user_filler(self):
for i in userdata:
self[i.id] = '%s, %s', (i.firstname, i.lastname)
return self.items()

Regards,
Lokesh

Bobby Roberts

unread,
May 17, 2009, 1:28:42 PM5/17/09
to Django users
> Try this below code. I guess this will solve your purpose
>
>  # pull a recordset of the users
>  userdata = auth_user.objects.all()
>
>  def user_filler(self):
>      for i in userdata:
>          self[i.id] = '%s, %s', (i.firstname, i.lastname)
>      return self.items()
>


from django import forms
from django.contrib.auth.models import User

# pull a recordset of the users
userdata = User.objects.all()

def myuserlist(self):
for i in userdata:
self[i.id]='%s %s', (i.first_name,i.last_name) <<<ERROR HERE
return self.items()

#used to post messages to oher users
class FrmIdMessage (forms.Form):
posted_to = forms.ChoiceField
(required=True,widget=forms.CheckboxSelectMultiple(attrs=
{'class':'optchecklist'},choices=myuserlist(userdata)))
message = forms.CharField (max_length=300, required=True,
widget=forms.Textarea(attrs={'class':'smallblob'}))


I get a traceback at line 9 (flagged with <<< ERROR HERE above)

Traceback is : QuerySet' object does not support item assignment


Lokesh

unread,
May 17, 2009, 1:35:08 PM5/17/09
to Django users
oops, please modify the line from "self[i.id]='%s %s',
(i.first_name,i.last_name)" to "self[i.id]='%s %s' %
(i.first_name,i.last_name) "

Bobby Roberts

unread,
May 17, 2009, 1:41:31 PM5/17/09
to Django users
> oops, please modify the line from "self[i.id]='%s %s',
> (i.first_name,i.last_name)"  to "self[i.id]='%s %s' %
> (i.first_name,i.last_name) "


this results in the same issue:

from django import forms
from django.contrib.auth.models import User

# pull a recordset of the users
userdata = User.objects.all()

def myuserlist(self):
for i in userdata:
self[i.id]='%s %s' %(i.first_name,i.last_name)
return self.items()

#used to post messages to oher users
class FrmIdMessage (forms.Form):
posted_to = forms.ChoiceField
(required=True,widget=forms.CheckboxSelectMultiple(attrs=
{'class':'optchecklist'},choices=myuserlist(userdata)))
message = forms.CharField (max_length=300, required=True,
widget=forms.Textarea(attrs={'class':'smallblob'}))

~

Sam Chuparkoff

unread,
May 17, 2009, 4:14:54 PM5/17/09
to django...@googlegroups.com
On Sun, 2009-05-17 at 10:41 -0700, Bobby Roberts wrote:
> from django import forms
> from django.contrib.auth.models import User
>
> # pull a recordset of the users
> userdata = User.objects.all()
>
> def myuserlist(self):
> for i in userdata:
> self[i.id]='%s %s' %(i.first_name,i.last_name)
> return self.items()
>
> #used to post messages to oher users
> class FrmIdMessage (forms.Form):
> posted_to = forms.ChoiceField
> (required=True,widget=forms.CheckboxSelectMultiple(attrs=
> {'class':'optchecklist'},choices=myuserlist(userdata)))
> message = forms.CharField (max_length=300, required=True,
> widget=forms.Textarea(attrs={'class':'smallblob'}))

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


Bobby Roberts

unread,
May 17, 2009, 4:23:08 PM5/17/09
to Django users

> ...     users = forms.ModelMultipleChoiceField(
> ...         queryset=User.objects,
> ...         widget=forms.CheckboxSelectMultiple,
> ...         required=True)
> ...>>> User(username='sdc').save()
> >>> User(username='bobby').save()


dude you rock... i totally missed this. Does exactly what i need!

Bobby Roberts

unread,
May 17, 2009, 9:43:37 PM5/17/09
to Django users
On May 17, 4:23 pm, Bobby Roberts <tchend...@gmail.com> wrote:
> > ...     users = forms.ModelMultipleChoiceField(
> > ...         queryset=User.objects,
> > ...         widget=forms.CheckboxSelectMultiple,
> > ...         required=True)
> > ...>>> User(username='sdc').save()
> > >>> User(username='bobby').save()
>

ok so here's what i have so far:

class FrmIdMessage (forms.Form):
posted_to = forms.ModelMultipleChoiceField (queryset=User.objects,
required=True,widget=forms.CheckboxSelectMultiple())
message = forms.CharField (max_length=300, required=True,
widget=forms.Textarea(attrs={'class':'smallblob'}))



in my view i have this:


if request.method=='POST':
form=FrmIdMessage(request.POST)
if form.is_valid(): #process valid form here
assert False, request.POST.get('posted_to','')
[snip]



The only that prints out is:

2

which represents the last textbox checked. The HTML generated by the
form.py includes:

<li><label for="id_posted_to_0"><input type="checkbox"
name="posted_to" value="1" id="id_posted_to_0" /> admin</label></li>
<li><label for="id_posted_to_1"><input type="checkbox"
name="posted_to" value="2" id="id_posted_to_1" /> test</label></li>
<li><label for="id_posted_to_2"><input type="checkbox"
name="posted_to" value="4" id="id_posted_to_2" /> test2</label></li>


all of these checkboxes have the same name. Why isn't this passed
back to forms.py as a list? How can i get all of the values for the
checkboxes if i check all three?

Bobby Roberts

unread,
May 17, 2009, 9:49:30 PM5/17/09
to Django users
On May 17, 4:23 pm, Bobby Roberts <tchend...@gmail.com> wrote:
> > ...     users = forms.ModelMultipleChoiceField(
> > ...         queryset=User.objects,
> > ...         widget=forms.CheckboxSelectMultiple,
> > ...         required=True)
> > ...>>> User(username='sdc').save()
> > >>> User(username='bobby').save()
>

ok so here's what i have so far:

class FrmIdMessage (forms.Form):
posted_to = forms.ModelMultipleChoiceField (queryset=User.objects,
required=True,widget=forms.CheckboxSelectMultiple())
message = forms.CharField (max_length=300, required=True,
widget=forms.Textarea(attrs={'class':'smallblob'}))



Bobby Roberts

unread,
May 17, 2009, 9:50:01 PM5/17/09
to Django users
On May 17, 4:23 pm, Bobby Roberts <tchend...@gmail.com> wrote:
> > ...     users = forms.ModelMultipleChoiceField(
> > ...         queryset=User.objects,
> > ...         widget=forms.CheckboxSelectMultiple,
> > ...         required=True)
> > ...>>> User(username='sdc').save()
> > >>> User(username='bobby').save()
>

ok so here's what i have so far:

class FrmIdMessage (forms.Form):
posted_to = forms.ModelMultipleChoiceField (queryset=User.objects,
required=True,widget=forms.CheckboxSelectMultiple())
message = forms.CharField (max_length=300, required=True,
widget=forms.Textarea(attrs={'class':'smallblob'}))



Sam Chuparkoff

unread,
May 17, 2009, 10:23:51 PM5/17/09
to django...@googlegroups.com
On Sun, 2009-05-17 at 18:43 -0700, Bobby Roberts wrote:
> in my view i have this:
>
>
> if request.method=='POST':
> form=FrmIdMessage(request.POST)
> if form.is_valid(): #process valid form here
> assert False, request.POST.get('posted_to','')
> [snip]

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


Bobby Roberts

unread,
May 17, 2009, 11:01:08 PM5/17/09
to Django users
> You should be looking in cleaned_data, see:
>
> http://docs.djangoproject.com/en/1.0/topics/forms/#processing-the-dat...
>
> For a ModelMultipleChoiceField, cleaned_data will be a list of model
> instances. You shouldn't even have to think about the pk s.
>
> sdc

yeah i'm still lost... this is what i have now:



forms.py


class FrmIdMessage (forms.Form):
posted_to = forms.ModelMultipleChoiceField (queryset=User.objects,
required=True,widget=forms.CheckboxSelectMultiple())
message = forms.CharField (max_length=300, required=True,
widget=forms.Textarea(attrs={'class':'smallblob'}))

def clean_posted_to(self):
data=self.cleaned_data['posted_to']
return data


still results in the last checkbox checked... I'm not sure what to do
in the clean function













views.py

#process or just push form

Sam Chuparkoff

unread,
May 18, 2009, 12:48:11 AM5/18/09
to django...@googlegroups.com
On Sun, 2009-05-17 at 20:01 -0700, Bobby Roberts wrote:
> yeah i'm still lost...

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


Reply all
Reply to author
Forward
0 new messages