Django Forms和Bootstrap - CSS类和<divs>

vic*_*ooi 66 css django twitter-bootstrap

我正在使用Twitter Bootstrap和Django来渲染表单.

Bootstrap可以很好地格式化你的表单 - 只要你有CSS它期望包含的类.

但是,我的问题是Django生成的表单{{ form.as_p }}不能很好地与Bootstrap一起呈现,因为它们没有这些类.

例如,Django的输出:

    <form class="horizontal-form" action="/contact/" method="post">
        <div style='display:none'>
            <input type='hidden' name='csrfmiddlewaretoken' 
                   value='26c39ab41e38cf6061367750ea8c2ea8'/>
        </div>
        <p><label for="id_name">Name:</label> <input id="id_name" type="text" name="name" value="FOOBAR" maxlength="20" /></p>
        <p><label for="id_directory">Directory:</label> <input id="id_directory" type="text" name="directory" value="FOOBAR" maxlength="60" /></p>
       <p><label for="id_comment">Comment:</label> <textarea id="id_comment" rows="10" cols="40" name="comment">Lorem ipsum dolor sic amet.</textarea></p>
       <p>
           <label for="id_server">Server:</label>
           <select name="server" id="id_server">
               <option value="">---------</option>
               <option value="1" 
                   selected="selected">sydeqexcd01.au.db.com</option>
               <option value="2">server1</option>
               <option value="3">server2</option>
               <option value="4">server3</option>
           </select>
       </p>
       <input type="submit" value="Submit" />
    </form>
Run Code Online (Sandbox Code Playgroud)

据我所知,Bootstrap要求你的表单有一个<fieldset class="control-group">,每个<label>都有class="control-label",每个<input>都包含在<div>:

<fieldset class="control-group">
    <label class="control-label" for="input01">Text input</label>
    <div class="controls">
        <input type="text" class="xlarge" name="input01">
        <p class="help-text">Help text here. Be sure to fill this out like so, or else!</p>
    </div>
</fieldset>
Run Code Online (Sandbox Code Playgroud)

但是,在Django中为每个表单字段添加自定义CSS标签是相当痛苦的:

将类添加到Django label_tag()输出

是否有更智能的方式使用{{ form.as_p }}或迭代字段,而不必手动指定事物,或做一大堆hackery?

干杯,维克多

小智 53

这就是我想出的:

<form class="form-horizontal" method="post">{% csrf_token %}
    <fieldset>
        <legend>{{ title }}</legend>
        {% for field in form %}
            {% if field.errors %}
                <div class="control-group error">
                    <label class="control-label">{{ field.label }}</label> 
                    <div class="controls">{{ field }}
                        <span class="help-inline">
                            {% for error in  field.errors %}{{ error }}{% endfor %}
                        </span>
                    </div>
                </div>
            {% else %}
                <div class="control-group">
                    <label class="control-label">{{ field.label }}</label> 
                    <div class="controls">{{ field }}
                        {% if field.help_text %}
                            <p class="help-inline"><small>{{ field.help_text }}</small></p>
                        {% endif %}
                    </div>
                </div>
            {% endif %}
        {% endfor %}
    </fieldset>
    <div class="form-actions">
        <button type="submit" class="btn btn-primary" >Submit</button>
    </div>
</form>
Run Code Online (Sandbox Code Playgroud)

  • 那真是太棒了!谢谢.我希望最终能够使标签成为连接到文本框侧面的跨度.我猜我需要安装一些其他软件包来管理它. (2认同)

eri*_*kcw 47

我喜欢使用"django-crispy-forms",它是django-uni-form的继承者.这是一个很棒的小API,并且对Bootstrap有很好的支持.

当我需要更多地控制渲染时,我倾向于使用模板过滤器来快速移植旧代码和快速表单,以及模板标记.

  • @NathanGould 2016年仍然是正确的吗? (7认同)
  • 我刚检查了django-crispy-forms github页面,它看起来很活跃.所以这可能是一个不错的选择.(但是,我不是最新的.) (5认同)
  • 我认为这是2014年的"正确"答案. (4认同)
  • Repo在2017年看起来仍然活跃 (2认同)

Iod*_*nas 39

django-crispy-forms不能使用时(例如,当模板单独处理表单的每个字段时),jcmrgo的答案是唯一的方法.根据他的回答,这里是Bootstrap 3的解决方案(将他的版本留给Boostrap 2),并调整模板内的字段类.虽然使用Django的标准库(在其他解决方案中导致额外的表单或模板标记)无法从模板中访问字段类,但这里有一个解决方案,可以将正确的类设置为字段标记,而无需在模板外部进行编码:

{% load i18n widget_tweaks %}

<form class="form-horizontal" role="form" action="." method="post">
    {% csrf_token %}
    {% for field in form %}
        {% if field.errors %}
            <div class="form-group has-error">
                <label class="col-sm-2 control-label" for="id_{{ field.name }}">{{ field.label }}</label>
                <div class="col-sm-10">
                    {{ field|attr:"class:form-control" }}
                    <span class="help-block">
                        {% for error in  field.errors %}{{ error }}{% endfor %}
                    </span>
                </div>
            </div>
        {% else %}
            <div class="form-group">
                <label class="col-sm-2 control-label" for="id_{{ field.name }}">{{ field.label }}</label>
                <div class="col-sm-10">
                    {{ field|attr:"class:form-control" }}
                    {% if field.help_text %}
                        <p class="help-block"><small>{{ field.help_text }}</small></p>
                    {% endif %}
                </div>
            </div>
        {% endif %}
    {% endfor %}
    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
            <button type="submit" class="btn btn-primary">{% trans "Submit" %}</button>
        </div>
    </div>
</form>
Run Code Online (Sandbox Code Playgroud)

这需要django-widget-tweaks安装和widget_tweaks添加INSTALLED_APPS.

  • 截至2015年,这是最好的答案.特别是如果你匆忙(需要交付)而不是在心情/没有时间学习*另一个*库像脆的形式.非常感谢先生! (4认同)
  • 截至2016年,这仍然是轻松整合的最佳答案,无需学习清晰. (2认同)
  • 截至2018年,这仍然是最好的答案.我喜欢它在模板中保留演示文稿的东西,而不是脆弱的形式,这迫使我把它放在python代码中.而且,我喜欢起床和跑步相当简单.我唯一的建议是使用"渲染字段"而不是过滤器,这将在下面的另一个答案中更详细地描述. (2认同)

c4u*_*elf 10

你可以这样做:

{% for field in form %}
<fieldset class="control-group">
    <label class="control-label" for="id_{{ field.name }}">{{ field.label }}</label>
    <div class="controls">
        {{ field }}
        <p class="help-text">{{ field.help_text }} </p>
    </div>
</fieldset>
{% endfor %}
Run Code Online (Sandbox Code Playgroud)


小智 8

为了向Django生成的表单添加CSS属性,只需在forms.py中使用以下代码即可:

Recepient = forms.ChoiceField(label=u'Recepient', widget=forms.Select(attrs={'id':'combobox'}))
Run Code Online (Sandbox Code Playgroud)

它将生成以下HTML代码:

<label for="id_Recepient">Recepient</label>
<select id="combobox" name="Recepient">
Run Code Online (Sandbox Code Playgroud)