wake-up-neo.net

Django: Wie kann ich ein Multiple-Select-Formular erstellen?

Ich bin ein Anfänger in Django/Python und muss ein Multiple-Select-Formular erstellen. Ich weiß, es ist einfach, aber ich kann kein Beispiel finden. Ich weiß, wie man ein CharField mit einem Widget erstellt, aber ich verwirrt alle Optionen in fields.py .

Ich weiß zum Beispiel nicht, welche der folgenden Optionen für ein Multiple-Select-Formular am besten geeignet ist.

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

Und hier ist das Formular, das ich erstellen muss.

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

BEARBEITEN:

Noch eine kleine Frage. Wenn ich zu jeder Option ein weiteres Attribut wie data hinzufügen möchte:

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

Wie kann ich es tun?

Danke für jede Hilfe!

11
CodeArtist

Ich denke, CheckboxSelectMultiple sollte funktionieren. Je nach Ihrem Problem müssen Sie in Ihrer forms.py den folgenden Code eingeben

from Django import forms

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

EDIT: Ich dachte daran, den gesamten Code-Fluss zu schreiben, damit Sie ihn besser verstehen können. Weil Sie vielleicht verwirrt werden

Definieren Sie in Ihrer Views.py die folgende Funktion

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

In deiner render_country.html

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

Ich hoffe, das hilft. Lassen Sie mich wissen, ob Sie das erwartet haben.

27
vibhor

Ich habe es so gemacht:

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

Ihre_Länder.html  

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

In meinem Beispiel funktioniert es gut. Wenn Sie mehr brauchen, fragen Sie mich einfach !! 

4
prog.Dusan

In Bezug auf meine zweite Frage ist dies die Lösung. Eine erweiterte Klasse:

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

Beispiel:

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

ModelMultipleChoiceField ist dein Freund. Ein CharField ist in der Lage, eine Auswahl zu speichern, jedoch nicht mehrere, ohne zusätzliche Arbeit, die ich empfehlen würde.

API-Dokument für ModelMultipleChoiceField

1
Brandon

Sie können auch ein Länderfeld in Ihrer Formularklasse als definieren 

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

Ich weiß nicht, welche in SelectMultiple und CheckboxSelectMultiple besser ist, aber es funktioniert auch.

Für weitere Informationen können Sie die Django-Dokumentation zu widgets verwenden.

1
Navjot Gwal