2010-04-28 71 views
30

Tengo una aplicación Django y quiero mostrar casillas de verificación de opción múltiple en el perfil de un usuario. Luego podrán seleccionar múltiples elementos.Django Campo de selección múltiple/Casilla de verificación Seleccionar múltiple

Ésta es una versión simplificada de mi 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) 

Y mi clase de formulario:

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

    class Meta: 
     model = Profile 

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

puedo ver que el POST solo envía un valor:

choice_field u'choice_three' 

y lo local Vars params es el envío de una lista:

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

Todos los campos del formulario de presentación correcta, pero cuando envío una POST, me sale un error

Error binding parameter 7 - probably unsupported type.

¿Necesito para procesar el campo de elección múltiple más en la vista? ¿Es correcto el tipo de campo del modelo? Cualquier ayuda o referencia sería muy apreciada.

+0

¿Puedes publicar el seguimiento completo de la pila por el error que obtienes al realizar la POST? – ars

+0

Posible duplicado de [Django Model MultipleChoice] (http://stackoverflow.com/questions/27440861/django-model-multiplechoice) – lechup

Respuesta

31

Las opciones de perfil deben configurarse como ManyToManyField para que esto funcione correctamente.

Así que ... su modelo debe ser como este:

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) 

A continuación, sincronizar la base de datos y la carga hasta opciones con las diversas opciones que desee que estén disponibles.

Ahora, el ModelForm construirá en sí ...

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

Y, por último, la vista:

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

Cabe mencionar que usted puede configurar un perfil en un par de maneras diferentes, incluida la herencia. Dicho esto, esto también debería funcionar para ti.

Buena suerte.

+0

Gracias Brant. Tuviste razón al señalar que necesitaba usar una relación ManyToManyField para mi tipo de modelo. – twampss

+4

Tenga en cuenta que debe llamar a save_m2m() en la instancia de formulario cuando usa guardar (confirmar = falso), o los cambios en las relaciones no se guardarán. Ver http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method – jakewins

+0

Estoy intentando implementar esto pero estoy obteniendo 'NameError: name 'TheChoice' no está definido ' –

12

La solución de Brant es absolutamente correcta, pero tuve que modificarla para que funcione con múltiples casillas de selección y commit=false. Aquí está mi solución:

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

algún consejo sobre cómo representar el campo de opción múltiple en la plantilla django? – Deven

12

El models.CharField es una representación de una de CharField las opciones. Lo que quieres es un conjunto de opciones. Esto no parece ser implementado en django (todavía).

Usted podría usar un campo de muchos para muchos, pero tiene la desventaja de que las opciones deben colocarse en una base de datos. Si desea usar opciones codificadas, probablemente esto no sea lo que desea.

Hay un fragmento de Django en http://djangosnippets.org/snippets/1200/ que hace parecen resolver el problema, mediante la implementación de un ModelField MultipleChoiceField.

+0

Gracias por el enlace del fragmento, solucionó mi problema. – mhost

Cuestiones relacionadas