在Django中向表单动态添加新字段

时间:2015-10-27 07:47:59

标签: django django-forms

我想让我的用户写内容,我希望他们指定他们想要拥有的标题的部分。我已经创建了一个小的Javascript函数来将新元素插入到将要提交的现有表单中。目前看起来像这样:

openTextarea.js

var i = 1;

function opentextarea() {
  "use strict";
  var hr = document.createElement('hr');
  var title = document.createElement('input');
  title.type = 'text';
  title.name = 'title_'+i;
  title.placeholder = 'Your section title!';
  title.className = 'form-control';
  var input = document.createElement('textarea');
  input.name = 'section_'+i;
  input.className = 'tiny-mce-init';
  var button = document.createElement('button');
  var newSection = document.getElementById('newSection');
  var form = document.getElementById('guide_form');
  form.appendChild(hr);
  form.appendChild(title);
  form.appendChild(input);
  loadTinyMCEEditor();
  i++;
}

模板

{% extends "base.html" %}

{% load staticfiles %}
{% block body %}

<script type="text/javascript" src="{% static "tinymce/js/tinymce/tinymce.min.js" %}"></script>
<script type="text/javascript" src="{% static "javascripts/openTextarea.js" %}"></script>
<script type="text/javascript" src="{% static "javascripts/loadTinyMCEEditor.js" %}"></script>

<div style="width: 60%; margin: 0 auto;">

  <hr>

  <form id="guide_form" class="form-horizontal" method="POST" action="{{ request.get_full_path }}"> {% csrf_token %}

    <fieldset>
      {% if form.title.errors %}
        <div class="class-group error">
          <div class="controls">{{ field }}
            <span class="help-inline">
              {% for error in form.title.errors %}{{ error }}{% endfor %}
            </span>
          </div>
        </div>
      {% else %}
        <div class="control-group">
          <div class="controls">{{ form.title }}</div>
        </div>
      {% endif %}

    <hr>

      {% if form.public.errors %}
        <div class="class-group error">
          <div class="controls">Check, if you want to make your guide public {{ field }}
            <span class="help-inline">
              {% for error in form.public.errors %}{{ error }}{% endfor %}
            </span>
          </div>
        </div>
      {% else %}
        <div class="control-group">
          <div class="controls">Check, if you want to make your guide public {{ form.public }}</div>
        </div>
      {% endif %}

    <hr>

    Neutral cards

    <hr>

    {% for card in form.cards %}
      {{ card }}
    {% endfor %}

    <hr>

    </fieldset>
  </form>

<hr>

<div id="newSection"></div>
<button class="btn btn-primary" type="button"
  onclick="opentextarea();">
  Add Section!
</button>

<hr>

<div class="form-actions" style="margin-top: 4px;">
  <button type="submit" form="guide_form" class="btn btn-success">Submit</button>
</div>

</div>

{% endblock %}

当我检查元素时,新部分会出现在表单中。

enter image description here

显然新部分不在form.cleaned_data中,因为当我打印出来时,我只是收到我最初使用表单创建的字段:

class CreateGuide(FormView):
    template_name = 'hsguides/guide_create.html'
    form_class = GuideForm
    success_url = '/guides/search-guide/'

    def get_form_kwargs(self, *args, **kwargs):
        form_kwargs = super(CreateGuide, self).get_form_kwargs(**kwargs)
        form_kwargs['hero'] = self.kwargs['hero']
        return form_kwargs

    def form_valid(self, form, *args, **kwargs):
        # TODO
        # - check if cards are actually from selected class...
        # - implement sections
        form.instance.author = self.request.user
        form.instance.hero = Hero.objects.get(name=self.kwargs['hero'])
        dust = 0
        for card in form.cleaned_data['cards']:
            dust += Card.objects.get(id=card.id).dust

        for foo in form.cleaned_data:
            print(foo)

        form.instance.dust = dust
        form.save()
        return super(CreateGuide, self).form_valid(form)

结果

  

     

公共

     

标题

这是有道理的,因为我的表单看起来像这样

class GuideForm(BootstrapModelForm):
    class Meta:
        model = Guide
        exclude = ('author', 'created', 'modified', 'hero', 'dust', 'rating',)

    def __init__(self, *args, **kwargs):
        hero = kwargs.pop('hero', None)
        super(GuideForm, self).__init__(*args, **kwargs)
        if hero:
            self.fields['cards'].queryset = Card.objects.filter(Q(card_class='neutral') |
                                                                Q(card_class=hero))
        self.fields['title'].widget.attrs['placeholder'] = 'Title of your awesome guide!'
        self.fields['public'].widget.attrs.update({'class': 'checkbox'})

如何在django中动态地将新元素添加到表单中?任何帮助或建议高度赞赏!

1 个答案:

答案 0 :(得分:3)

您可以在调用super之后添加它们。

class GuideForm(BootstrapModelForm):
    class Meta:
        model = Guide
        exclude = ('author', 'created', 'modified', 'hero', 'dust', 'rating',)

    def __init__(self, *args, **kwargs):
        hero = kwargs.pop('hero', None)
        super(GuideForm, self).__init__(*args, **kwargs)

        #  add your fields here
        self.fields['title_1'] = forms.CharField()

您可以查看这个好例子https://stackoverflow.com/a/6142749/2698552