2010-09-01 73 views
4

当我显示ToolBoxEditForm时,它使用了一个多选字段。 但我想要的是一种让用户可以在工具箱中将每个工具编辑为文本字段的形式。我无法弄清楚如何在多对多领域做到这一点。如何在多对多的情况下将多个选择字段更改为多个输入字段?

class Tool(models.Model): 
    tool_name = models.CharField(unique=True, max_length=200) 
...... 

class ToolBox(models.Model): 
    tools = models.ManyToManyField(Tool,max_length=300) 

class ToolBoxEditForm (ModelForm): 
    tools = ??? 
    class Meta: 
     model = ToolBox 
     exclude = ('user', 'popularity',) 

回答

2

最性感的解决方案

你可以使用这里描述了jQuery autocommplete工具之一:Facebook style JQuery autocomplete plugin

然后形式:

class ToolBoxEditForm (ModelForm): 
    tools = forms.CharField(widget=forms.Textarea, required=False) 

    def clean_tools(self): 
     tool_data = self.cleaned_data.get('tools',None) 
     tools = [] 
     #here, a comma is used a delim, so it's not allowed in the tool name. 
     for td in tool_data.split(','): 
      t, _ = Tool.objects.get_or_create(name=td) 
      tools.append(t) 
     return tools 

    class Meta: 
     model = ToolBox 
     exclude = ('user', 'popularity',) 

你必须弄清楚如何修改JavaScript,以便可以输入新项目(即不只是es已经在数据库中)。

替代解决方案

这有点什么inline formsets被用于创建,因此Narendra's solution会奏效。

喜欢的东西:

from django.forms.models import inlineformset_factory 

def manage_toolbox(request, toolbox_id): 
    toolbox = Toolbox.objects.get(pk=toolbox_id) 
    ToolInlineFormSet = inlineformset_factory(Toolbox, Tool) 
    if request.method == "POST": 
     formset = ToolInlineFormSet(request.POST, request.FILES, instance=toolbox) 
     if formset.is_valid(): 
      formset.save() 
      # Do something. 
    else: 
     formset = ToolInlineFormSet(instance=toolbox) 
    return render_to_response("manage_toolbox.html", { 
     "formset": formset, 
    }) 

这并不是说这种形式是只用于编辑工具箱内的物品。如果您希望用户能够编辑工具箱的其他方面 - 例如其名称或描述 - 您可以创建一个单独的表单并在同一个<form></form>标签内输出它们。

+0

这正是我最终做的!我使用jquery方法。它的作品非常漂亮。谢谢! – adeleinr 2010-10-14 23:15:46

0

我不确定,因为没有测试它,但这里是逻辑。

  1. 创建通过formset_factory
  2. 变化tool_name字段类型表单集的ToolBoxEditForm到CharField
  3. 在表单集的行集数以dB为单位精确对象工具的数量可用
  4. 通行证的首字母来FORMSET构造填写tool_name文本框。

    #TODO:下列数据必须被动态生成

    initial_data = [{ 'tool_name':u'first_tool_name '},{ 'tool_name':u'second_tool_name',}]

    表单集= ToolBoxFormSet(extra = 0,initial = initial_data)

不确定验证部分。这里我们将tool_name作为textbox的值。在验证过程中,Form可能需要ID(因为它应该是列表框)。但是,你也可以处理。

有关表单集更多信息请参阅:http://docs.djangoproject.com/en/dev/topics/forms/formsets/