2010-04-28 7 views
30

Ich habe eine Django-Anwendung und möchte Multiple-Choice-Checkboxen in einem Benutzerprofil anzeigen. Sie können dann mehrere Elemente auswählen.Django Multiple Choice Feld/Checkbox Mehrere auswählen

Dies ist eine vereinfachte Version meiner models.py:

from profiles.choices import SAMPLE_CHOICES 

class Profile(models.Model): 
    user = models.ForeignKey(User, unique=True, verbose_name_('user')) 
    choice_field = models.CharField(_('Some choices...'), choices=SAMPLE_CHOICES, max_length=50) 

Und meine Form-Klasse:

class ProfileForm(forms.ModelForm): 
    choice_field = forms.MultipleChoiceField(choices=SAMPLE_CHOICES, widget=forms.CheckboxSelectMultiple) 

    class Meta: 
     model = Profile 

Und mein views.py:

if request.method == "POST": 
    profile_form = form_class(request.POST, instance=profile) 
    if profile_form.is_valid(): 
     ... 
     profile.save() 
return render_to_response(template_name, {"profile_form": profile_form,}, context_instance=RequestContext(request)) 

ich sehen kann dass der POST nur einen Wert sendet:

choice_field u'choice_three' 

Und die lokale Vars params sendet eine Liste:

[u'choice_one', u'choice_two', u'choice_three'] 

alle Formularfelder korrekt angezeigt, aber wenn ich einen Post einreichen, erhalte ich einen Fehler

Error binding parameter 7 - probably unsupported type.

Muss ich das Multiple-Choice-Feld in der Ansicht weiter zu bearbeiten? Ist der Modellfeldtyp korrekt? Jede Hilfe oder Referenzen würden sehr geschätzt werden.

+0

Können Sie den vollständigen Stack-Trace für den Fehler, den Sie beim POSTing erhalten, posten? – ars

+0

Mögliches Duplikat von [Django Model MultipleChoice] (http://stackoverflow.com/questions/27440861/django-model-multiplechoice) – lechup

Antwort

31

Die Profilauswahl muss als ManyToManyField eingerichtet werden, damit dies ordnungsgemäß funktioniert.

So ... Ihr Modell so sein sollte:

class Choices(models.Model): 
    description = models.CharField(max_length=300) 

class Profile(models.Model): 
    user = models.ForeignKey(User, blank=True, unique=True, verbose_name='user') 
    choices = models.ManyToManyField(Choices) 

Dann die Datenbank synchronisieren und Auswahl mit den verschiedenen Optionen laden Sie zur Verfügung stehen sollen.

Nun bauen die Modelform wird sich ...

class ProfileForm(forms.ModelForm): 
    Meta: 
    model = Profile 
    exclude = ['user'] 

Und schließlich die Ansicht:

if request.method=='POST': 
    form = ProfileForm(request.POST) 
    if form.is_valid(): 
    profile = form.save(commit=False) 
    profile.user = request.user 
    profile.save() 
else: 
    form = ProfileForm() 

return render_to_response(template_name, {"profile_form": form}, context_instance=RequestContext(request)) 

Es sollte erwähnt werden, ein Profil in ein paar verschiedene Möglichkeiten, dass man konnte Setup, einschließlich Vererbung. Trotzdem sollte dies auch für Sie funktionieren.

Viel Glück.

+0

Danke Brant. Sie haben richtigerweise darauf hingewiesen, dass ich eine ManyToManyField-Beziehung für meinen Modelltyp verwenden musste. – twampss

+4

Beachten Sie, dass Sie save_m2m() in der Formularinstanz aufrufen müssen, wenn Sie save (commit = false) verwenden oder Änderungen an den Beziehungen nicht gespeichert werden. Siehe http://docs.djangoproject.com/de/dev/topics/forms/modelforms/#the-save-method – jakewins

+0

Ich versuche dies zu implementieren, aber ich bekomme 'NameError: Name 'TheChoice' ist nicht definiert ' –

12

Brants Lösung ist absolut korrekt, aber ich musste es ändern, damit es mit mehreren Auswahlkästchen funktioniert und commit=false. Hier ist meine Lösung:

models.py

class Choices(models.Model): 
    description = models.CharField(max_length=300) 

class Profile(models.Model): 
    user = models.ForeignKey(User, blank=True, unique=True, verbose_name_('user')) 
    the_choices = models.ManyToManyField(Choices) 

forms.py

class ProfileForm(forms.ModelForm): 
    the_choices = forms.ModelMultipleChoiceField(queryset=Choices.objects.all(), required=False, widget=forms.CheckboxSelectMultiple) 

    class Meta: 
     model = Profile 
     exclude = ['user'] 

views.py

if request.method=='POST': 
    form = ProfileForm(request.POST) 
    if form.is_valid(): 
     profile = form.save(commit=False) 
     profile.user = request.user 
     profile.save() 
     form.save_m2m() # needed since using commit=False 
    else: 
     form = ProfileForm() 

return render_to_response(template_name, {"profile_form": form}, context_instance=RequestContext(request)) 
+0

Tipps, wie das Multi-Choice-Feld in der Django-Vorlage zu rendern? – Deven

12

Die models.CharField ist eine CharField Darstellung eines die Auswahlmöglichkeiten. Was Sie wollen, ist eine Reihe von Möglichkeiten. Dies scheint (noch) nicht im Django implementiert zu sein.

Sie könnte verwenden Sie ein Viel zu viele Feld dafür, aber das hat den Nachteil, dass die Auswahlmöglichkeiten in einer Datenbank gespeichert werden müssen. Wenn Sie hartcodierte Optionen verwenden möchten, ist dies wahrscheinlich nicht das, was Sie wollen.

Es ist ein django Schnipsel an http://djangosnippets.org/snippets/1200/ dass tut scheint Ihr Problem zu lösen, indem eine ModelField MultipleChoiceField implementieren.

+0

Danke für den Snippet-Link, es löste mein Problem. – mhost

Verwandte Themen