【问题标题】:Adding fields to a Django form dynamically with JavaScript & JSONField使用 JavaScript 和 JSONField 向 Django 表单动态添加字段
【发布时间】:2012-03-01 01:13:41
【问题描述】:

我有一个模型表单,我需要在其中存储未知数量的助手和一个东西。名称可以在保存时序列化,这不是问题。它能够在提交时清理和验证它们。

表格的样子;

class ThingForm(forms.ModelForm):
    """
    Form for the Thing
    """
    owner = forms.CharField()
    helpers = forms.CharField()

    class Meta:
        model = Thing

    def save(self, *args, **kwargs):
        """
        Serialize helpers to JSON.
        """
        ...

并且模型使用 JSONField 来存储序列化的助手。

class Thing(models.Model):
    owner = models.CharField()
    helpers = JSONField()

我让 JavaScript 根据需要使用相同的输入名称添加多个帮助器:

<input name="helpers" value="Fred" />
<input name="helpers" value="Joe" />

返回一个帮助者的元组。 问题是如果表单无效 - 这些名称将会丢失并且清理工作不起作用。

我的第一个想法是添加到表单的构造函数中:

    def __init__(self, *args, **kwargs):
        super(ThingForm, self).__init__(*args, **kwargs)
        try:
            helpers = args[0].pop('helpers')
            for name in helpers:
                # Add a charfield, or something?
        except:
            pass

但我并没有真正到达任何地方......

【问题讨论】:

    标签: javascript django django-forms


    【解决方案1】:

    我们遇到了类似的问题,但没有找到现成的解决方案。所以我们做了我们的 (https://github.com/vialink/vlk-django-jsonfield)。

    【讨论】:

      【解决方案2】:

      感谢AdamKG 对此的回答。您可以再次使用视图中的列表:

      查看:

      if request.method == 'POST':
          helpers = request.POST.getlist('helpers')
          form = ThingForm(request.POST)
          if form.is_valid():
              form.save()
              return HttpResponseRedirect('/saved/')
      else:
          helpers = None
          form = ThingForm()
      
      return render_to_response('my_template.html',
          {'helpers': helpers, 'form': form},
          context_instance=RequestContext(request))
      

      模板:

      {% for field in form %}
          {% if field.name == 'helpers' %}
              {% for name in helpers %}
                  <input name="helpers" value="{{ name }}" />
              {% endfor %}
          {% else %}
              {{ field }}
          {% endif %}
      {% endfor %}
      

      【讨论】:

        【解决方案3】:

        我认为你需要做的就是在你的模板中做这样的事情:

        {% if form.data %}{# eg, was invalid and this is a re-render w/ errors #}
        {% for helper in form.data.helpers %}
        <input type="hidden" name="helpers" value="{{ helper }}">
        {% endfor %}
        {% endif %}
        

        请注意,如果您开始将 prefix kwarg 传递给您的表单,这将中断 - 但您的原始代码也会如此,修复这是一个单独的问题 :)

        【讨论】:

        • 问题是额外的助手被表单清理了,所以当我们到达模板时它们并不存在。
        • 这是您添加的干净方法吗?它应该仍然在form.data 中,只要您将与request.POST 绑定的表单传递回模板以呈现错误。
        • 不,现在的表格很普通。如果我在模板中使用该迭代器并且它只是迭代最后一个输入中的字母(form.data.helpers 中只有一个字符串)
        • 啊,对。仅访问 helpers 键不会为您提供列表。您需要将 {'prev_helpers': request.POST.getlist("helpers")} 作为上下文传递给模板并对其进行迭代。
        • BTW - 如果有任何错误,.cleaned_data 将被完全清除;只有.is_valid() 成功,它才会被填充。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-14
        • 1970-01-01
        • 2023-03-24
        • 1970-01-01
        相关资源
        最近更新 更多