如何在多对多情况下将多个选择字段更改为多个输入字段?

ade*_*inr 5 django django-models django-forms

当我显示 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',)
Run Code Online (Sandbox Code Playgroud)

Jor*_*ter 2

最性感的解决方案

您可以使用此处描述的 jquery 自动完成工具之一:Facebook 风格的 JQuery 自动完成插件

然后采用以下形式:

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',)
Run Code Online (Sandbox Code Playgroud)

您必须弄清楚如何修改 JavaScript,以便可以输入新项目(即不仅仅是数据库中已有的项目)。

替代解决方案

这就是创建内联表单集的目的,因此Narendra 的解决方案将起作用。

就像是:

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,
    })
Run Code Online (Sandbox Code Playgroud)

并不是说此表单仅用于编辑工具箱中的项目。如果您希望用户能够编辑工具箱的其他方面(例如,其名称或描述),您可以创建一个单独的表单并将它们输出到相同的<form></form>标签内。