2010-04-28 1787 views
30

我有一个Django应用程序,并希望在用户的配置文件中显示多选复选框。他们将能够选择多个项目。Django多选字段/复选框选择多个

这是我的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) 

我的表单类:

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

    class Meta: 
     model = Profile 

而且我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)) 

我可以看到该POST仅发送一个值:

choice_field u'choice_three' 

而且本地变量params为发送列表:

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

所有表单字段的显示是正确的,但是当我提出一个帖子,我得到一个错误

Error binding parameter 7 - probably unsupported type.

我需要在视图中进一步处理多选字段?模型字段类型是否正确?任何帮助或引用将不胜感激。

+0

您可以发布完整的堆栈跟踪,以获取发布时的错误吗? – ars 2010-04-28 04:32:38

+0

[Django Model MultipleChoice]的可能重复(http://stackoverflow.com/questions/27440861/django-model-multiplechoice) – lechup 2016-08-16 20:19:36

回答

31

配置文件选择需要设置为ManyToManyField才能正常工作。

所以......你的模型应该是这样的:

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) 

然后,同步数据库,并加载选择你想要的各种选择。

现在,将的ModelForm自身建设......

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

最后,认为:

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

应该提到的是,你可以设置在几个不同的方式配置文件,包括继承。也就是说,这也适用于你。

祝你好运。

+0

谢谢勃兰特。你指出我需要为我的模型类型使用ManyToManyField关系是正确的。 – twampss 2010-04-29 04:28:04

+4

请注意,当您使用save(commit = false)时,您需要在表单实例上调用save_m2m(),否则不会保存关系的更改。见http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method – jakewins 2010-11-03 19:24:56

+0

我想实现这个,但我得到了'NameError:name'TheChoice'未定义' – 2011-08-31 19:20:41

12

Brant的解决方案是绝对正确的,但我需要修改它以使其能够与多个选择复选框和commit=false一起使用。这里是我的解决方案:

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

关于如何在django模板中呈现多选字段的任何建议? – Deven 2018-01-25 07:57:35

12

的models.CharField是之一的CharField表示选择。你想要的是一组选择。这似乎并没有在django(还)中实现。

可能使用多对多的领域,但它的缺点是选择必须放在数据库中。如果你想使用硬编码的选择,这可能不是你想要的。

有一个django片段http://djangosnippets.org/snippets/1200/确实似乎解决您的问题,通过执行ModelField MultipleChoiceField

+0

感谢您的代码链接,它解决了我的问题。 – mhost 2012-03-18 22:28:12