【问题标题】:Django CrispyForms - Render every form of a formset in separate bootstrap tabsDjango CrispyForms - 在单独的引导选项卡中呈现表单集的每种形式
【发布时间】:2015-05-09 07:11:55
【问题描述】:

我想使用 django-crispyForms 在不同的 bootstrap3 选项卡中呈现表单集的每个表单,但这似乎并不简单,因为 KrispyForms 还没有完全处理表单集。

我的表格:

class BlogMessageForm(forms.ModelForm):
    class Meta:
        model = BlogMessage
        fields = ['field1', 'field2', ]

class BlogMessageFormsetHelper(FormHelper):
    def __init__(self, *args, **kwargs):
        super(BlogMessageFormsetHelper, self).__init__(*args, **kwargs)
        self.form_tag = False
        self.layout = Layout(
            TabHolder(
                Tab('Form%s' % (form.pk),
                    'field1', 'field2', 'DELETE',
                    )
             )

        )

我的看法:

def all_blogs_messages_in_bootstrap_tab(request):
  all_blog_messages = BlogMessage.objects.all()
  blogMessageForm = modelformset_factory(BlogMessage, form=BlogMessageForm, extra=1, can_delete=True)
  formset = blogMessageForm(queryset=all_blog_messages)
  helper = BlogMessageFormHelper()

  render_to_response("blogs/blogMessage_forms.html", {'formset': formset, 'helper': helper}, context_instance=RequestContext(request))

我的 crispyForms 模板:

{% load crispy_forms_tags %}
<form method="post" action="" encrypt="multipart/form-data">{% csrf_token %}
    {% crispy formset helper %}
</form>

这里有一些关于crispyForm formset 约束的信息:

【问题讨论】:

  • 只需遍历表单集中的表单并调用 crisy 的表单渲染器。您只需要在 forloop 中包装/创建选项卡代码。
  • 是的,如果有一个清晰的模板来做这件事,那就太好了。如果有人可以创建这样的模板,我明天会为此开一个赏金。

标签: django twitter-bootstrap-3 django-crispy-forms


【解决方案1】:

我会这样做:

<form method="post" enctype="multipart/form-data">{% csrf_token %}
  {{ formset.management_form }}
  <div role="tabpanel">
    <ul class="nav nav-tabs" role="tablist">
      {% for form in formset %}
        <li role="presentation" class="{% if forloop.first %}active{% endif %}">
          <a href="#id_form-{{ forloop.counter0 }}" aria-controls="id_form-{{ forloop.counter0 }}" role="tab" data-toggle="tab">
            {% if forloop.counter0 < formset.initial_forms|length %}
              Form{{ forloop.counter }}
            {% else %}
              New Form
            {% endif %}
          </a>
        </li>
      {% endfor %}
    </ul>
    <div class="tab-content">
      {% for form in formset %}
        <div role="tabpanel" class="tab-pane{% if forloop.first %} active{% endif %}" id="id_form-{{ forloop.counter0 }}">
          {% crispy form %}
          {% if form.instance.pk %}
             <input id="id_form-{{ forloop.counter0 }}-id" name="form-{{ forloop.counter0 }}-id" type="hidden" value="{{ form.instance.id }}">
          {% endif %}
          {% if forloop.counter0 < formset.initial_forms|length %}
            {% if formset.can_delete %}
              <input id="id_form-{{ forloop.counter0 }}-DELETE" name="form-{{ forloop.counter0 }}-DELETE" type="hidden">
              <button type="submit" data-id="id_form-{{ forloop.counter0 }}-DELETE" class="btn btn-default btn-formset-delete">Delete</button>
            {% endif %}
          {% endif %}
        </div>
      {% endfor %}
    </div>
  </div>
  <button type="submit" class="btn btn-primary">Save</button>
</form>

差点忘了,如果没有一些 javascript,删除按钮将无法工作。但这当然是可选的,delete 字段可以设为可见并移除按钮,否则:

$(document).ready(function(){
    $(".btn-formset-delete").click(function(){
        $("#" + $(this).data('id')).val("on");
        return true;
    });
});

也将其添加到表单中:

def __init__(self, *args, **kwargs):
    super(MyForm, self).__init__(*args, **kwargs)
    self.helper = FormHelper(self)
    self.helper.form_tag = False
    self.helper.disable_csrf = True

【讨论】:

  • 干得好阿列克谢!然而,唯一的事情是“form-0-id”隐藏输入没有添加到表单集的每个表单中,所以我无法保存。你知道为什么吗?
  • 我做了一个小的调整,应该可以解决这个问题。如果该字段仍未显示,请告诉我。
  • 好的,我想您可以将隐藏的表单 ID 输入放在 {% if form.instance %} 中吗?但是,我不明白为什么此输入不会与所有其他表单一起自动添加
  • 你是对的,但最好检查pk 而不是例如:{% if form.instance.pk %},因为每个表单实际上都有一个与之关联的实例:github.com/django/django/blob/master/django/forms/… 不知道为什么该字段不会自动呈现。
  • 您好@lehins,在此之后这篇文章仍然有用,非常感谢。我正在构建一个动态表单选项卡。而这个解决方案几乎是完美的。我在“form-0-id”中也有一个问题,我需要有“form_0_id”,因为我对某些属性使用自定义小部件并且生成了 js 动态名称,并且我得到了“2873 Uncaught SyntaxError: Unexpected token '-' ',我克隆了 formsets.py 以更改 add_prefix(),以应用该逻辑,但即使没有任何更改也无法正常工作。错误是,列表索引必须是整数或切片,而不是“def __getitem__(self, index):”中的 str,知道吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-25
  • 1970-01-01
  • 2022-07-07
相关资源
最近更新 更多