2013-03-13 14 views
8

Sono principiante in Django/Python e ho bisogno di creare un modulo di selezione multipla. So che è facile ma non riesco a trovare alcun esempio. So come creare un CharField con un widget ma mi confondo di tutte le opzioni all'interno di fields.py.Django: come posso creare un modulo di selezione multipla?

Ad esempio, non conosco quale dei seguenti è il migliore per un modulo di selezione multipla.

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

Ed ecco il modulo che ho bisogno di creare.

 <form action="" method="post" accept-charset="utf-8"> 
     <select name="countries" id="countries" class="multiselect" multiple="multiple"> 
      <option value="AUT" selected="selected">Austria</option> 
      <option value="DEU" selected="selected">Germany</option> 
      <option value="NLD" selected="selected">Netherlands</option> 
      <option value="USA">United States</option> 
     </select> 
     <p><input type="submit" value="Continue &rarr;"></p> 
    </form> 

EDIT:

più Uno piccola domanda. Se voglio aggiungere a ogni opzione un attributo più come dati:

<option value="AUT" selected="selected" data-index=1>Austria</option> 

Come posso fare?

Grazie per qualsiasi aiuto!

risposta

23

penso CheckboxSelectMultiple dovrebbe funzionare. Secondo il vostro problema, Nella tua forms.py wirite il codice qui sotto

from django import forms 

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

EDIT: ho pensato di scrivere il flusso di codice completo così che si può capire meglio. Perché si potrebbe ottenere confondere

Nella tua Views.py definire la seguente funzione

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)) 

Nella tua render_country.html

<form method='post'> 
    {% csrf_token %} 
    {{ form.as_p }} 
    <input type='submit' value='submit'> 
</form> 

Spero che questo helps.Let me sapere se questo è ciò che ti aspettavi.

+0

Sì, questa è una cosa ancora più piccola ... Se voglio aggiungere a ciascuna opzione una proprietà dati come questa Germany come posso fallo? Manca anche l'ultima opzione che non è selezionata. Grazie comunque – CodeArtist

+1

Non sono sicuro !! forma la forma come modello. Credo quindi che nel backend verrà associata una chiave primaria. Devi controllarlo. – vibhor

+1

e se la mia prima risposta soddisfa la tua domanda, considera di accettare la risposta. :) – vibhor

4

ho fatto in questo modo:

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

<form action="" method="post"> 
    {% csrf_token %} 
    {{ form.as_table }} 
    <input type="submit" value="Submit" /> 
</form> 

Funziona bene nel mio esempio, se avete bisogno di qualcosa di più, chiedetemi!

2

Riguardo alla mia seconda domanda questa è la soluzione.Una classe che estende:

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'<option value="{0}"{1}{2}>{3}</option>'.format(
       escape(option_value), selected_html, attrs_html, 
       conditional_escape(force_unicode(option_label)) 
       ) 
      ''' 
      return u'<option value="%s"%s%s>%s</option>' % (
       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'<optgroup label="%s">' % escape(force_unicode(option_value))) 
       for option in option_label: 
        output.append(render_option(*option)) 
       output.append(u'</optgroup>') 
      else: 
       output.append(render_option(option_value, option_label, 
        option_attrs)) 
     return u'\n'.join(output) 

class SelectMultiple(forms.SelectMultiple, Select): 
    pass 

Esempio:

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

È anche possibile definire campo paesi nella classe forma

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

non so che uno è migliore in selectMultiple e CheckboxSelectMultiple ma funziona anche.

Per ulteriori dettagli è possibile utilizzare la documentazione di django su widgets.

Problemi correlati