Получить вид виджета формы Django из шаблона
Я повторяю поля формы и для определенных полей хочу немного другой макет, требующий изменения HTML.
Чтобы сделать это точно, мне просто нужно знать тип виджета. Его название класса или что-то подобное. В стандартном питоне это легко! field.field.widget.__class__.__name__
К сожалению, вам не разрешен доступ к символам подчеркивания в шаблонах. Отлично!
Вы можете протестировать field.field.widget.input_type
, но это работает только для типов text/password <input ../>
. Мне нужно больше разрешения.
Мне, как бы сложно это ни казалось, имеет смысл сделать это на уровне шаблона. Я передал часть кода, обрабатывающего HTML для полей, в отдельный шаблон, который включается в цикл цикла. Это означает, что он согласован между ModelForm
и стандартным Form
(что-то, что не было бы правдой, если бы я написал промежуточный класс формы).
Если вы видите универсальный подход, который не требует от меня редактирования 20-тичных форм, дайте мне знать!
Ответы
Ответ 1
Как и в Django 1.11, вы можете просто использовать widget.input_type
. Пример:
{% for field in form.visible_fields %}
<input type="{{ field.field.widget.input_type }}"
id="{{ field.id_for_label }}"
name="{{ field.html_name }}"
placeholder="{{ field.label }}"
maxlength="{{ field.field.max_length }}" />
{% endfor %}
Ответ 2
Создание тега шаблона может работать? Что-то вроде field.field.widget|widget_type
Править от Оли: Хорошая мысль! Я просто написал фильтр:
from django import template
register = template.Library()
@register.filter('klass')
def klass(ob):
return ob.__class__.__name__
И теперь {{ object|klass }}
корректно отображает. Теперь мне нужно выяснить, как использовать это внутри шаблона if
.
Edit from Oli # 2: Мне нужно было использовать результат этого в шаблоне if statetement in-template, поэтому я просто переместил всю эту логику в templatetag. Магия. Спасибо, что тыкал меня в правильном направлении.
Ответ 3
Следуя принятому ответу - расширенный if tag
в Django 1.2 позволяет использовать фильтры в сравнении if tag
. Таким образом, теперь вы можете сделать свой собственный html/logic в шаблоне следующим образом:
<ul>
{% for field in form.fields %}
<li>
{% if field.field.widget|klass == "Textarea" %}
<!-- do something special for Textarea -->
<h2>Text Areas are Special </h2>
{% else %}
{{ field.errors }}
{{ field.label_tag }}
{{ field }}
{% endif %}
</li>
{% endfor %}
</ul>
Ответ 4
После ответа от Oli и rinti: я использовал этот, и я думаю, что это немного проще:
код шаблона: {{ field|fieldtype }}
код фильтра:
from django import template
register = template.Library()
@register.filter('fieldtype')
def fieldtype(field):
return field.field.widget.__class__.__name__