Django 模板根据条件渲染每个表单字段

Posted

技术标签:

【中文标题】Django 模板根据条件渲染每个表单字段【英文标题】:Django template render each form field based on criteria 【发布时间】:2015-02-14 15:16:45 【问题描述】:

我将 Django 1.7 与 bootstrap 3 一起使用,并希望以相同的方式呈现每个表单字段,最好利用 bootstrap has-error 字段:

<div class="form-group % if form.field.errors %has-error has-feedback% endif %">
    <label class="control-label" for="field"> form.field.help_text </label>

    <div class="input-group">
        <span class="input-group-addon"><span class="some-icon"></span></span>
        % render_field form.field class+="form-control" placeholder=form.field.label id="end-date" aria-describedby="inputError2Status" %
    </div>
    <label class="control-label" for="field"> form.field.errors.as_text </label>
</div>

正如你所看到的,当字段数量增加的那一刻,它就变成了很多工作,不仅要编写它,还要维护它,重构变成了地狱……并不是真的 DRY。对于每个字段,我需要更改 form.field 变量和 id="field" 以及图标

我将如何编写函数、模板标签或其他东西来让 django 以这种方式呈现我表单中的所有字段?甚至有可能做到这一点吗?如果 django 中的表单有一个设置来接受可选的glypycon class 渲染器将使用它来渲染图标,那就太棒了。

-- 编辑--

正如@Serafeim 所示,django-crispy-forms 可能是解决方案。但是如何使用crispy-forms 来生成上面的html呢?

-- 编辑 2--

在阅读了脆皮表格后,我设法提出了以下解决方案: 我的 forms.py 文件如下所示:

class CreateForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(CreateForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_method = 'post'
        self.helper.form_action = 'submit'
        self.helper.add_input(Submit('submit', 'Submit'))
        self.helper.html5_required = True
        self.helper.layout = Layout(
            PrependedText('fieldA', '<span class="fa fa-calendar"></span>', placeholder="yyyy-mm-dd"),
            PrependedText('fieldB', '<span class="fa fa-clock-o"></span>', placeholder="0:00:00 (h:m:s)"),
        'fieldC')

    fieldA = forms.DateField(required=True)
    fieldB = FDurationField(required=True)
    fieldC = forms.CharField(widget=forms.Textarea(attrs='rows':3), required=False, max_length=128)

    class Meta:
        model = AModel
        exclude = ('fieldD', 'FieldE', 'fieldF', 'fieldG')

在我的模板中,我只需要调用% crispy form %,这比我的初始版本要好得多。但是,我仍然觉得我必须重复某些步骤,例如将字段添加到布局中......是否可以进一步减少代码?

【问题讨论】:

你听说过 django-crispy-forms django-crispy-forms.readthedocs.org/en/latest 吗?试试吧,它会解决你所有的问题:) 我有,并且我已经尝试过了,但我无法让它按照我想要的方式工作......也许我只是没有以正确的方式使用它......不幸的是我无法向您显示我使用脆表单的代码,不久前将其删除:( 【参考方案1】:

如果 django 中的表单有一个设置,那就太棒了 接受渲染器将用于渲染的可选 glypycon 类 图标。

表单只是字段的集合。 Field 是 widget(控制呈现的 HTML)和验证规则的组合。

要控制页面上呈现的内容,您需要修改小部件。

例如,如果我想指定一个 css 类或占位符,我会在小部件级别执行此操作:

email = forms.EmailField(label='Email Address',
                         required=False,
                         widget=forms.TextInput(attrs='class': 'form-control',
                                                       'placeholder': 'user@example.com'))

您可以创建自己的自定义小部件和字段,并对表单的呈现方式进行精细控制;所以你问的是绝对可能的;但由于这是经常重复的事情,django-crispy-forms 已成为完成这项工作的事实上的标准方式。

【讨论】:

感谢您提供的信息。我不知道 attrs 参数,这已经有帮助了。正如我在(更新的)问题中提到的那样。你能举一个例子来说明需要做什么来呈现我的代码中的字段吗? 我用新的crispy-forms 代码更新了我的问题。

以上是关于Django 模板根据条件渲染每个表单字段的主要内容,如果未能解决你的问题,请参考以下文章

带有 ReactJS 的 Django 表单

使用模板渲染 django 小部件?

Django模板表单字段以无序方式显示

django 模板:如何知道表单字段类型并根据字段类型添加任何按钮

django表单的Widgets

Django - 在模板中呈现日期字段