Django формы и Bootstrap-CSS классы и
Я использую Twitter Bootstrap С Django для визуализации форм.
Bootstrap
может форматировать ваши формы довольно красиво - до тех пор, пока у вас есть CSS
классы, которые он ожидает включены.
однако, моя проблема заключается в том, что формы, созданные Django's {{ 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>
из того, что я могу сказать, 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>
однако добавление пользовательских меток CSS в каждое поле формы в Django довольно болезненно:
добавить класс в Django label_tag () output
есть ли более умный способ использования {{ form.as_p }}
, или итерации по полям, без необходимости вручную указывать вещи, или сделать целую кучу хакерства?
Ура, Виктор
10 ответов:
Мне нравится использовать "в Django-хрустящие-форм" который является преемником django-uni-form. Это отличный маленький API и имеет большую поддержку Bootstrap.
Я обычно использую фильтры шаблонов для быстрого переноса старого кода и быстрых форм, а также теги шаблонов, когда мне нужно больше контролировать рендеринг.
вот что я придумал:
<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>
, когда
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>
Это
django-widget-tweaks
установлен иwidget_tweaks
добавилINSTALLED_APPS
.
вы могли бы сделать что-то вроде этого:
{% 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 %}
чтобы добавить атрибуты CSS в генерируемые Django формы, достаточно использовать следующий код в вашем forms.py:
Recepient = forms.ChoiceField(label=u'Recepient', widget=forms.Select(attrs={'id':'combobox'}))
Он будет производить следующий HTML-код:
<label for="id_Recepient">Recepient</label> <select id="combobox" name="Recepient">
Я определенно рекомендую https://github.com/dyve/django-bootstrap-toolkit
например, вы можете создать класс, который определяет атрибуты так, как вы хотите, и просто вызвать его соответствующим образом.
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)
самый быстрый и простой способ-определить свой собственный базовый класс, который расширяет класс формы Django, и переопределить его
as_p
метод вывода в формате Bootstrap требуется. Затем измените свои формы, чтобы наследовать от вашего нового класса формы вместо Django.
Bootstrap стили формы с
<div>
s, а не<p>
s. Итак, если вы хотите, чтобы это выглядело красиво, вам нужно пойти bootstrap way 100% IMHO. И вот мой предпочтительный способ сделать это:использовать django-bootstrap3 приложение. Пример:
{% 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>
обратите внимание на
horizontal
в 1) атрибут класса формы 2) макет bootstrap_form и 3) макет кнопок.
вот моя версия с использованием django_tweaks с более привлекательным результатом. Я нахожу render_field легче использовать, чем добавление фильтров. Я также добавил сообщения оповещения в формате bootstrap и отключил проверку навигатора (с помощью novalidate). Я относительно новичок в Django, поэтому не стесняйтесь комментировать, если вы найдете какой-либо смысл
<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>