template form fields example custom crispy bootstrap css django twitter-bootstrap

fields - Django Forms and Bootstrap-Clases de CSS y<divs>



django forms fields (10)

Estoy usando Twitter Bootstrap con Django para renderizar formularios.

Bootstrap puede formatear sus formularios bastante bien, siempre y cuando tenga incluidas las clases de CSS .

Sin embargo, mi problema es que los formularios generados por {{ form.as_p }} Django no se {{ form.as_p }} bien con Bootstrap, ya que no tienen estas clases.

Por ejemplo, la salida de 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>

Por lo que puedo decir, Bootstrap requiere que sus formularios tengan un <fieldset class="control-group"> , cada <label> tiene class="control-label" , y cada <input> está envuelto en un <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>

Sin embargo, añadir etiquetas CSS personalizadas a cada campo de formulario en Django es bastante doloroso:

Agregar clase a Django label_tag () salida

¿Existe alguna forma más inteligente de usar {{ form.as_p }} , o de iterar por los campos, sin tener que especificar cosas manualmente, o hacer un montón de hackers?

Saludos, Victor


Aquí está mi versión usando django_tweaks con un mejor resultado. Encuentro render_field más ligero para usar que agregar filtros. También agregué mensajes de alerta con formato de arranque y apagué la validación del navegador (sin validación). Soy relativamente nuevo en Django, así que no dudes en comentar si encuentras algo sin sentido

<form class="large" method="post" action="/suscript/" novalidate> {% csrf_token %} <fieldset> <legend>{{ title }}</legend> {% for field in form %} <div class="control-group {%if field.errors %}error{%endif%}"> <div class="input-group controls"> <label class="input-group-addon control-label" id="{{field.label|safe}}">{{ field.label }}</label> {% render_field field type="text" class="form-control" placeholder="" aria-describedby="field.label|safe" %} </div> {% for error in field.errors %} <div class="alert alert-danger"> <strong>{{ error|escape }}</strong> </div> {% endfor %} {% if field.help_text %} <p class="help-inline">{{ field.help_text|safe }}</p> {% endif %} </div> {% endfor %} </fieldset> <div class="form-actions"> <button type="submit" class="btn btn-primary" >Submit</button> </div> </form>


Bootstrap styles se forma con <div> s en lugar de <p> s. Por lo tanto, si quieres que se vea bien, debes ir al modo bootstrap 100% en mi humilde opinión. Y esta es mi forma preferida de hacerlo:

Utilice la aplicación django-bootstrap3 . Ejemplo:

{% load bootstrap3 %} <form class="signup form-horizontal" id="signup_form" method="post" action="{% url ''account_signup'' %}"> {% csrf_token %} {% bootstrap_form form layout="horizontal" %} {% buttons submit=''Sign Up &raquo;'' reset=''Reset Form'' layout=''horizontal'' %}{% endbuttons %} </form>

Observe que la horizontal en 1) forma el atributo de clase 2) diseño bootstrap_form y 3) diseño de botones.


Cuando django-crispy-forms no se pueden usar (por ejemplo, cuando la plantilla trata individualmente cada campo del formulario), la respuesta de jcmrgo es la única manera de hacerlo. Según su respuesta, aquí hay una solución para Bootstrap 3 (dejando su versión para Boostrap 2) y con el ajuste de las clases de campo dentro de la plantilla . Si bien las clases de campo no son alcanzables desde la plantilla con la biblioteca estándar de Django (que conduce a formularios adicionales o etiquetas de plantilla en otras soluciones), aquí hay una solución que establece las clases correctas para etiquetas de campo sin tener que codificar fuera de la plantilla:

{% 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>

Esto necesita django-widget-tweaks instalado y widget_tweaks agregados a INSTALLED_APPS .



Esto es lo que se me ocurrió:

<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>


La forma más rápida y sencilla sería definir su propia clase base que amplíe la clase Django Form y redefinir su método as_p para que se emita en el formato que requiere Bootstrap. Luego cambie sus formularios para heredarlos de su nueva clase Form en lugar de Django.


Me gusta usar "django-crispy-forms" que es el sucesor de django-uni-form. Es una gran pequeña API y tiene un gran soporte para Bootstrap.

Tiendo a utilizar los filtros de plantilla para trasladar rápidamente el código antiguo y los formularios rápidos, y las etiquetas de plantilla cuando necesito más control sobre el renderizado.


Para agregar atributos de CSS a los formularios generados por Django es suficiente usar el siguiente código en su forms.py:

Recepient = forms.ChoiceField(label=u''Recepient'', widget=forms.Select(attrs={''id'':''combobox''}))

Producirá el siguiente código HTML:

<label for="id_Recepient">Recepient</label> <select id="combobox" name="Recepient">


Podrías hacer algo como esto:

{% 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 %}


Por ejemplo, podría crear una clase que defina los atributos de la manera que desee y simplemente llámelo en consecuencia.

class ContactForm(ModelForm): class Meta: model = Contact created = MyDatePicker() class Uniform(forms): def __init__(self, *args, **kwargs): attrs = kwargs.pop("attrs",{}) attrs["class"] = "span3" kwargs["attrs"] = attrs super(Uniform, self).__init__(*args, **kwargs) class MyDatePicker(Uniform,forms.DateInput) def __init__(self, *args, **kwargs): attrs = kwargs.pop("attrs",{}) attrs["class"] = "datepick" attrs["id"] =kwargs.get(''datetag'', '''') kwargs["attrs"] = attrs super(MyDatePicker, self).__init__(*args, **kwargs)