Получить вид виджета формы 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__