У форм в Django есть несколько предопределенных методов as_p(), as_table() и as_ul(), которые отображают форму как набор параграфов, таблицу или список. На практике этих методов не всегда достаточно, чтобы формы выглядели так, как нам хочется.
Допустим, верстальщик сверстал все формы div-ами. Документация предлагает в этом случае писать нужные теги в ручную в шаблоне. Если форма у нас только одна, можно поступить и так. Если форм несколько, то этот подход сразу же теряет все свое очарование. Решение очень простое — пронаследуем наш собственный класс форм от forms.Form или forms.ModelForm и обучим его рисовать формы так, как нужно нам.
Для начала неплохо заглянуть в исходники Django – методы as_p и ему подобные устроены очень просто. Они вызывают метод _html_output класса BaseForm инструктируя его, как именно рисовать форму. Итак, добавим свой метод as_div:
Код самоочевиден, единственное, что может вызвать вопросы — это errors_on_separate_row. Если этот параметр установлен в True, то ошибки будут выводиться отдельным блоком. Он используется, например в as_p, чтобы не запихивать <ul> внутрь <p>.
Теперь, мы можем наследовать наши формы от SexyModelForm и вызывать их в шаблонах с помощью {{ form.as_div }}.
В 1.2. появилась приятная возможность назначать свои css-классы для обязательного поля и поля с ошибкой. Еще немного упростим себе жизнь — допишем пару строк в наш класс, и в формы добавится еще немного единообразия:
Но и это еще не все. Бывает нужно добавить всем полям какие-то css-классы. Это можно сделать вот так:
Здесь-же можно, например, проверять input_type и присваивать классы разным типам полей в зависимости от него.
Вот, что получилось в итоге:
Решение получилось простое, не захламляющее код и работоспособное.
Допустим, верстальщик сверстал все формы div-ами. Документация предлагает в этом случае писать нужные теги в ручную в шаблоне. Если форма у нас только одна, можно поступить и так. Если форм несколько, то этот подход сразу же теряет все свое очарование. Решение очень простое — пронаследуем наш собственный класс форм от forms.Form или forms.ModelForm и обучим его рисовать формы так, как нужно нам.
Для начала неплохо заглянуть в исходники Django – методы as_p и ему подобные устроены очень просто. Они вызывают метод _html_output класса BaseForm инструктируя его, как именно рисовать форму. Итак, добавим свой метод as_div:
Copy Source | Copy HTML
- class SexyModelForm(forms.ModelForm):
- def as_div(self):
- return self._html_output(
- normal_row = u'<div%(html_class_attr)s>%(label)s %(field)s %(help_text)s %(errors)s</div>',
- error_row = u'<div class="error">%s</div>',
- row_ender = '</div>',
- help_text_html = u'<div class="hefp-text">%s</div>',
- errors_on_separate_row = False)
Код самоочевиден, единственное, что может вызвать вопросы — это errors_on_separate_row. Если этот параметр установлен в True, то ошибки будут выводиться отдельным блоком. Он используется, например в as_p, чтобы не запихивать <ul> внутрь <p>.
Теперь, мы можем наследовать наши формы от SexyModelForm и вызывать их в шаблонах с помощью {{ form.as_div }}.
В 1.2. появилась приятная возможность назначать свои css-классы для обязательного поля и поля с ошибкой. Еще немного упростим себе жизнь — допишем пару строк в наш класс, и в формы добавится еще немного единообразия:
Copy Source | Copy HTML
- error_css_class = 'class-error'
- required_css_class = 'class-required'
Но и это еще не все. Бывает нужно добавить всем полям какие-то css-классы. Это можно сделать вот так:
Copy Source | Copy HTML
- def __init__(self, *args, **kwargs):
- super(ModelForm, self).__init__(*args, **kwargs)
- # adding css classes to widgets without define the fields:
- for field in self.fields:
- self.fields[field].widget.attrs['class'] = 'some-class other-class'
Здесь-же можно, например, проверять input_type и присваивать классы разным типам полей в зависимости от него.
Вот, что получилось в итоге:
Copy Source | Copy HTML
- class SexyModelForm(forms.ModelForm):
- error_css_class = 'class-error'
- required_css_class = 'class-required'
- def __init__(self, *args, **kwargs):
- super(ModelForm, self).__init__(*args, **kwargs)
- # adding css classes to widgets without define the fields:
- for field in self.fields:
- self.fields[field].widget.attrs['class'] = 'some-class other-class'
- def as_div(self):
- return self._html_output(
- normal_row = u'<div%(html_class_attr)s>%(label)s %(field)s %(help_text)s %(errors)s</div>',
- error_row = u'<div class="error">%s</div>',
- row_ender = '</div>',
- help_text_html = u'<div class="hefp-text">%s</div>',
- errors_on_separate_row = False)
Решение получилось простое, не захламляющее код и работоспособное.