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 →"></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!
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.
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 !!
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", {}]
]
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.
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.