Django-Crispy-Forms 中 {% crispy %} 标签处理表单集(formsets)的完整指南

Django-Crispy-Forms 中 {% crispy %} 标签处理表单集(formsets)的完整指南

django-crispy-forms The best way to have DRY Django forms. The app provides a tag and filter that lets you quickly render forms in a div format while providing an enormous amount of capability to configure and control the rendered HTML. django-crispy-forms 项目地址: https://gitcode.com/gh_mirrors/dj/django-crispy-forms

前言

Django-Crispy-Forms 是一个强大的 Django 第三方应用,它极大地简化了表单的渲染和布局过程。在前面的文章中,我们已经介绍了如何使用 {% crispy %} 标签来渲染单个表单。本文将深入探讨如何使用这个标签来处理更复杂的表单集(formsets)场景。

表单集基础概念

在 Django 中,表单集(formsets)允许我们在一个页面上处理多个表单实例。Django 提供了三种类型的表单集:

  1. 基础表单集(formsets)
  2. 模型表单集(modelformsets)
  3. 内联表单集(inline formsets)

虽然本文不会深入讲解 Django 表单集的基础知识,但理解这些概念对于后续内容非常重要。

基本表单集渲染

让我们从一个简单的示例开始。假设我们有一个 ExampleForm,我们可以这样创建一个表单集:

from django.forms.models import formset_factory

ExampleFormSet = formset_factory(ExampleForm, extra=3)
formset = ExampleFormSet()

在模板中,我们可以简单地使用 {% crispy %} 标签来渲染这个表单集:

{% crispy formset %}

使用 FormHelper 增强表单集

与单个表单一样,我们可以为表单集创建 FormHelper 类来定制其行为和外观。不过有一个关键区别:在表单集中,helper 的属性应用于整个表单结构,而布局(layout)则应用于表单集中的每个单独表单。

下面是一个为 ExampleFormSet 创建的 helper 示例:

from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Submit

class ExampleFormSetHelper(FormHelper):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.form_method = 'post'
        self.layout = Layout(
            'favorite_color',
            'favorite_food',
        )
        self.render_required_fields = True
        self.add_input(Submit('submit', 'Save'))

在视图中使用表单集 Helper

在视图函数中,我们需要同时传递表单集和 helper 到模板上下文:

def example_view(request):
    formset = ExampleFormSet()
    helper = ExampleFormSetHelper()
    return render(request, 'template.html', {'formset': formset, 'helper': helper})

在模板中,我们需要同时指定表单集和 helper:

{% crispy formset helper %}

添加提交按钮的两种方式

为表单集添加提交按钮有两种主要方法:

  1. 使用 FormHelper.add_input 方法:
helper.add_input(Submit("submit", "Save"))
  1. 手动控制表单结构:
<form action="{% url 'save_formset' %}" method="POST">
    {% crispy formset helper %}
    <div class="form-actions">
        <input type="submit" name="submit" value="Save" class="btn btn-primary">
    </div>
</form>

注意第二种方法需要设置 helper.form_tag = False

表单集渲染的额外上下文

在渲染表单集时,Django-Crispy-Forms 会注入一些额外的上下文变量,让你可以在布局中使用类似循环的功能:

class ExampleFormSetHelper(FormHelper):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.form_method = 'post'
        self.layout = Layout(
            HTML('{% if forloop.first %}仅在第一项显示...{% endif %}'),
            Fieldset('项目: {{forloop.counter}}', 'field'),
            'favorite_color',
            'favorite_food',
        )
        self.add_input(Submit('submit', 'Save'))

这样你就可以访问 forloop 变量,就像在常规 Django 模板循环中一样。

自定义模板和表格布局

默认情况下,表单集使用 div 布局渲染,但有时表格布局可能更合适。Django-Crispy-Forms 提供了专门的表格模板:

helper.template = 'bootstrap/table_inline_formset.html'

如果你想进一步自定义,可以复制这个模板到你的项目模板目录中并修改它。

重要提示:当前表格模板不支持自定义布局,且仅适用于 bootstrap 模板包。

为表单集中的不同表单设置不同布局

虽然大多数情况下表单集中的所有表单共享相同布局,但有时你可能需要为不同表单设置不同布局。这时你需要使用自定义模板:

{{ formset.management_form|crispy }}
{% for form in formset %}
    {% crispy form %}
{% endfor %}

在视图中,你需要为每个表单设置不同的 helper 或修改布局:

formset = ExampleFormSet()
helpers = []
for i, form in enumerate(formset):
    helper = ExampleFormSetHelper()
    if i == 0:
        helper.layout = Layout('special_field', 'favorite_color')
    else:
        helper.layout = Layout('favorite_color', 'favorite_food')
    form.helper = helper
    helpers.append(helper)

记得设置 helper.form_tag = False,否则会渲染多个独立的表单标签。

总结

通过 Django-Crispy-Forms,我们可以轻松地渲染和管理复杂的表单集,同时保持代码的整洁和可维护性。无论是基本的表单集渲染,还是高级的自定义布局需求,{% crispy %} 标签都提供了灵活而强大的解决方案。

记住,表单集的核心概念与单个表单相同,主要区别在于如何组织和控制多个表单的渲染。掌握了这些技巧后,你将能够处理 Django 项目中各种复杂的表单场景。

django-crispy-forms The best way to have DRY Django forms. The app provides a tag and filter that lets you quickly render forms in a div format while providing an enormous amount of capability to configure and control the rendered HTML. django-crispy-forms 项目地址: https://gitcode.com/gh_mirrors/dj/django-crispy-forms

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

章雍宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值