Django: ¿Cómo puedo crear un formulario de selección múltiple?

Soy principiante en Django / Python y necesito crear un formulario de selección múltiple. Sé que es fácil pero no puedo encontrar ningún ejemplo. Sé cómo crear un CharField con un widget, pero me confunden todas las opciones dentro de fields.py .

Por ejemplo, no sé cuál de los siguientes es el mejor para un formulario de selección múltiple.

'ChoiceField', 'MultipleChoiceField', 'ComboField', 'MultiValueField', 'TypedChoiceField', 'TypedMultipleChoiceField' 

Y aquí está la forma que necesito crear.

    Austria Germany Netherlands United States  

EDITAR:

    Una pequeña pregunta más. Si quiero agregar a cada opción un atributo más como datos :

      Austria 

    ¿Cómo puedo hacerlo?

    ¡Gracias por cualquier ayuda!

    Creo que CheckboxSelectMultiple debería funcionar. De acuerdo con su problema, en su formulario.

     from django import forms class CountryForm(forms.Form): OPTIONS = ( ("AUT", "Austria"), ("DEU", "Germany"), ("NLD", "Neitherlands"), ) Countries = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, choices=OPTIONS) 

    EDITAR: pensé en escribir el flujo de código completo para que pueda entenderlo mejor. Porque podrías confundirte

    En tu Views.py define la siguiente función

     def countries_view(request): if request.method == 'POST': form = CountryForm(request.POST) if form.is_valid(): countries = form.cleaned_data.get('countries') # do something with your results else: form = CountryForm return render_to_response('render_country.html', {'form':form }, context_instance=RequestContext(request)) 

    En tu render_country.html

     
    {% csrf_token %} {{ form.as_p }}

    Espero que esto te ayude. Hazme saber si es lo que estabas esperando.

    Lo hice de esta manera:

    forms.py

     class ChoiceForm(ModelForm): class Meta: model = YourModel def __init__(self, *args, **kwargs): super(ChoiceForm, self).__init__(*args, **kwargs) self.fields['countries'] = ModelChoiceField(queryset=YourModel.objects.all()), empty_label="Choose a countries",) 

    urls.py

     from django.conf.urls.defaults import * from django.views.generic import CreateView from django.core.urlresolvers import reverse urlpatterns = patterns('', url(r'^$',CreateView.as_view(model=YourModel, get_success_url=lambda: reverse('model_countries'), template_name='your_countries.html'), form_class=ChoiceForm, name='model_countries'),) 

    your_countries.html

     
    {% csrf_token %} {{ form.as_table }}

    Funciona bien en mi ejemplo, si necesitas algo más, ¡solo pregúntame!

    Respecto a mi segunda pregunta esta es la solución. Una clase que se extiende:

     from django import forms from django.utils.encoding import force_unicode from itertools import chain from django.utils.html import escape, conditional_escape class Select(forms.Select): """ A subclass of Select that adds the possibility to define additional properties on options. It works as Select, except that the ``choices`` parameter takes a list of 3 elements tuples containing ``(value, label, attrs)``, where ``attrs`` is a dict containing the additional attributes of the option. """ def render_options(self, choices, selected_choices): def render_option(option_value, option_label, attrs): option_value = force_unicode(option_value) selected_html = (option_value in selected_choices) and u' selected="selected"' or '' attrs_html = [] for k, v in attrs.items(): attrs_html.append('%s="%s"' % (k, escape(v))) if attrs_html: attrs_html = " " + " ".join(attrs_html) else: attrs_html = "" return u''.format( escape(option_value), selected_html, attrs_html, conditional_escape(force_unicode(option_label)) ) ''' return u'' % ( escape(option_value), selected_html, attrs_html, conditional_escape(force_unicode(option_label))) ''' # Normalize to strings. selected_choices = set([force_unicode(v) for v in selected_choices]) output = [] for option_value, option_label, option_attrs in chain(self.choices, choices): if isinstance(option_label, (list, tuple)): output.append(u'' % escape(force_unicode(option_value))) for option in option_label: output.append(render_option(*option)) output.append(u'') else: output.append(render_option(option_value, option_label, option_attrs)) return u'\n'.join(output) class SelectMultiple(forms.SelectMultiple, Select): pass 

    Ejemplo:

     OPTIONS = [ ["AUT", "Australia", {'selected':'selected', 'data-index':'1'}], ["DEU", "Germany", {'selected':'selected'}], ["NLD", "Neitherlands", {'selected':'selected'}], ["USA", "United States", {}] ] 

    ModelMultipleChoiceField es tu amigo. Un CharField es capaz de almacenar una selección, pero no múltiple, sin un trabajo extra, que recomendaría en contra.

    Documento de la API para ModelMultipleChoiceField

    También puede definir el campo de países en su clase de formulario como

     Countries = forms.MultipleChoiceField(widget=forms.SelectMultiple, choices=OPTIONS_TUPPLE) 

    No sé cuál es mejor en SelectMultiple y CheckboxSelectMultiple pero también funciona.

    Para más detalles puedes usar la documentación de django sobre widgets .