J'utilise Twitter Bootstrap avec Django pour rendre les formulaires.
Bootstrap
peut très bien formater vos formulaires, à condition que vous ayez les classes CSS
prévues.
Cependant, mon problème est que les formulaires générés par {{ form.as_p }}
ne rend pas bien avec Bootstrap, car ils n’ont pas ces classes.
Par exemple, la sortie 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>
D'après ce que je peux dire, Bootstrap nécessite que vos formulaires aient un <fieldset class="control-group">
, chaque <label>
a class="control-label"
, et chaque <input>
est enveloppé dans 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>
Cependant, ajouter des étiquettes CSS personnalisées à chaque champ de formulaire dans Django est plutôt pénible:
Ajouter une classe à la sortie Django label_tag () output
Existe-t-il un moyen plus intelligent d’utiliser {{ form.as_p }}
, ou en parcourant les champs, sans avoir à spécifier manuellement les choses, ou à faire tout un tas de hackery?
À la vôtre, Victor
J'aime utiliser "Django-crispy-forms" qui est le successeur de Django-uni-form. C'est une excellente petite API et supporte parfaitement Bootstrap.
J'ai tendance à utiliser les filtres de modèle pour porter rapidement du code ancien et des formulaires rapides, ainsi que les balises de modèle lorsque j'ai besoin de plus de contrôle sur le rendu.
Voici ce que je suis venu avec:
<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>
Quand Django-crispy-forms
_ ne peut pas être utilisé (par exemple, lorsque le modèle traite individuellement chaque champ du formulaire), la réponse de jcmrgo est la seule solution. Basé sur sa réponse, voici une solution pour Bootstrap 3 (laissant sa version pour Boostrap 2), et avec ajustement des classes de champs à l'intérieur du modèle . Bien que les classes de champs ne soient pas accessibles depuis le modèle avec la bibliothèque standard de Django (ce qui conduit à des formulaires supplémentaires ou des balises de modèles dans d'autres solutions), voici une solution qui définit les bonnes classes en balises de champs sans avoir à coder en dehors du modèle:
{% 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>
Cela nécessite Django-widget-tweaks
installé et widget_tweaks
ajouté à INSTALLED_APPS
.
Vous pouvez faire quelque chose comme ça:
{% 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 %}
Pour ajouter des attributs CSS à Django a généré des formulaires, il suffit d’utiliser le code suivant dans votre forms.py:
Recepient = forms.ChoiceField(label=u'Recepient', widget=forms.Select(attrs={'id':'combobox'}))
Il produira le code HTML suivant:
<label for="id_Recepient">Recepient</label>
<select id="combobox" name="Recepient">
Je recommande vraiment https://github.com/dyve/Django-bootstrap-toolkit
Voici ma version utilisant Django_tweaks avec un meilleur résultat. Je trouve render_field plus léger à utiliser que l'ajout de filtres. J'ai également ajouté bootstrap des messages d'alerte formatés et désactivé la validation du navigateur (avec novalidate). Je suis relativement nouveau sur Django, alors n'hésitez pas à commenter si vous trouvez un non-sens
<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>
Par exemple, vous pouvez créer une classe qui définit les attributs comme vous le souhaitez et appelez-la en conséquence.
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)
Les styles de bootstrap avec <div>
s plutôt que <p>
s. Donc, si vous voulez que ça ait l'air bien, vous devez y aller bootstrap façon 100% à mon humble avis. Et voici ma façon préférée de le faire:
Utilisez Django-bootstrap app. Exemple:
{% 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 »' reset='Reset Form' layout='horizontal' %}{% endbuttons %}
</form>
Remarquez l'attribut horizontal
in 1) de la classe de formulaire 2) la disposition bootstrap_form et la disposition 3) des boutons.
Le moyen le plus rapide et le plus simple serait de définir votre propre classe de base qui étend la classe Django Form, et de redéfinir sa as_p
la méthode de sortie au format Bootstrap nécessite. Ensuite, modifiez vos formulaires pour qu'ils héritent de votre nouvelle classe Form au lieu de ceux de Django.
outre ce que d'autres amis ont dit, je vous recommanderais d'utiliser 'Django-widget-tweaks'.
la réponse serait comme ça:
{% for field in form %}
<label for="{{ field.label }}">{{ field.label }}</label>
{{ field|add_class:"form-control" }}
<span class="error-block">{{ field.errors }}</span>
{% endfor %}