【问题标题】:How to change multiple select field to multiple input fields for a many-to-many case?对于多对多情况,如何将多个选择字段更改为多个输入字段?
【发布时间】:2010-09-01 17:27:07
【问题描述】:

当我显示 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',)

【问题讨论】:

    标签: django django-forms django-models


    【解决方案1】:

    最性感的解决方案

    您可以使用此处描述的 jquery 自动完成工具之一: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 以便可以输入新项目(即不仅仅是数据库中已有的项目)。

    替代解决方案

    这就是 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> 标记中。

    【讨论】:

    • 这正是我最终做的!我使用了 jquery 方法。它工作得很好。谢谢!
    【解决方案2】:

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

    1. 通过 formset_factory 为 ToolBoxEditForm 创建表单集
    2. 将 tool_name 字段类型更改为 CharField
    3. 将 formset 中的行数设置为 db 中可用的 Tool 对象数
    4. 将缩写传递给表单集构造函数以填充工具名称文本框。

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

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

      formset = ToolBoxFormSet(extra=0, initial=initial_data)

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

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

    【讨论】:

      猜你喜欢
      • 2016-01-15
      • 2011-02-05
      • 1970-01-01
      • 2017-02-01
      • 2021-06-22
      • 1970-01-01
      • 1970-01-01
      • 2011-05-30
      • 2012-10-13
      相关资源
      最近更新 更多