J'ai une application Django et je souhaite afficher plusieurs cases à cocher dans le profil d'un utilisateur. Il pourra alors sélectionner plusieurs éléments.
Ceci est une version simplifiée de mes 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)
Et ma classe de forme:
class ProfileForm(forms.ModelForm):
choice_field = forms.MultipleChoiceField(choices=SAMPLE_CHOICES, widget=forms.CheckboxSelectMultiple)
class Meta:
model = Profile
Et mon 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))
Je peux voir que le POST n'envoie qu'une seule valeur:
choice_field u'choice_three'
Et les paramètres locaux de vars envoient une liste:
[u'choice_one', u'choice_two', u'choice_three']
Tous les champs du formulaire s'affichent correctement, mais lorsque je soumets un POST, j'obtiens une erreur
Erreur de liaison du paramètre 7 - type probablement non pris en charge.
Dois-je traiter le champ à choix multiple plus loin dans la vue? Le type de champ de modèle est-il correct? Toute aide ou référence serait grandement appréciée.
Les choix de profil doivent être configurés en tant que ManyToManyField pour que cela fonctionne correctement.
Donc ... votre modèle devrait ressembler à ceci:
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)
Ensuite, synchronisez la base de données et chargez Choices avec les différentes options que vous souhaitez disponibles.
Maintenant, le ModelForm va se construire ...
class ProfileForm(forms.ModelForm):
Meta:
model = Profile
exclude = ['user']
Et enfin, la vue:
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))
Il convient de mentionner que vous pouvez configurer un profil de différentes manières, y compris l'héritage. Cela dit, cela devrait également fonctionner pour vous.
Bonne chance.
La solution de Brant est absolument correcte, mais je devais la modifier pour qu'elle fonctionne avec plusieurs cases à cocher et commit=false
. Voici ma solution:
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))
Les modèles.CharField est une représentation CharField de l'un des choix. Ce que vous voulez, c'est un ensemble de choix. Cela ne semble pas être implémenté dans Django (encore).
Vous pourriez utiliser un champ plusieurs à plusieurs pour cela, mais cela a l'inconvénient que les choix doivent être placés dans une base de données. Si vous souhaitez utiliser des choix codés en dur, ce n'est probablement pas ce que vous voulez.
Il y a un Django extrait de code à http://djangosnippets.org/snippets/1200/ que fait semble résoudre votre problème, en implémentant un ModelField MultipleChoiceField
.
ManyToManyField n'est pas un bon choix. Vous pouvez utiliser des extraits de code pour implémenter MultipleChoiceField .Vous pouvez vous inspirer de MultiSelectField avec des valeurs séparées par des virgules (Field + FormField) Mais il contient des bogues et vous pouvez installer Django-multiselectfield . C'est plus préfet.