2009-11-27 3 views
37

Я повторяю поля формы и для определенных полей хочу немного другой макет, требующий изменения HTML.Получить вид виджета формы Django из шаблона

Чтобы сделать это точно, мне просто нужно знать тип виджета. Его название класса или что-то подобное. В стандартном питоне это легко! field.field.widget.__class__.__name__

К сожалению, вы не имеете права доступа к символам подчеркивания в шаблонах. Отлично!

Вы можете тест field.field.widget.input_type, но это работает только для текстовых/паролей <input ../> типов. Мне нужно больше разрешения.

Для меня, как бы сложно это ни выглядело, имеет смысл сделать это на уровне шаблона. Я передал часть кода, обрабатывающего HTML для полей, в отдельный шаблон, который включается в цикл цикла. Это означает, что он согласован между ModelForm и стандартом Form s (что-то, что не было бы правдой, если бы я написал промежуточный класс формы).

Если вы видите универсальный подход, который не требует от меня редактирования 20-тичных форм, дайте мне знать!

+0

Соответствующий отчет об ошибке или функция запроса: https://code.djangoproject.com/ticket/13009 – Flimm

ответ

4

по Джанго 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 %} 
40

Возможно создание шаблона? Что-то вроде field.field.widget|widget_type

Редактировать от Oli: Хорошая точка! Я просто написал фильтр:

from django import template 
register = template.Library() 

@register.filter('klass') 
def klass(ob): 
    return ob.__class__.__name__ 

И теперь {{ object|klass }} делает правильно. Теперь я только должен выяснить, как использовать это внутри оператора шаблона if.

Редактировать от Oli # 2: Мне нужно использовать результат этого в шаблоне if statetement in-template, поэтому я просто переместил всю эту логику в templatetag. Магия. Спасибо, что тыкаешь меня в правильном направлении.

+0

Добро пожаловать на SO кстати. – Oli

+1

Спасибо за это решение. Что касается Edit # 2 - с расширенными 'if tags' в Django 1.2, вы можете выполнить эти сравнения типов виджетов прямо в шаблоне. Я привел пример как отдельный ответ. – zlovelady

+1

Еще один хороший фильтр для добавления (если люди, не относящиеся к Python, будут обрабатывать ваши шаблоны), это примерно так: для ваших наиболее часто используемых случаев: 'def is_checkboxes (form_field_obj): return (form_field_obj .__ class __.__ name__ ==" CheckboxSelectMultiple ")' ... тогда вы можете сделать '{% if field | is_checkboxes%}', и люди не будут freak out (... no returns) – hangtwenty

33

В соответствии с принятым ответом - расширенный if tag в Django 1.2 позволяет использовать фильтры в сравнении if tag. Таким образом, вы могли теперь сделать свой пользовательский HTML/логика в шаблоне так:

<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> 
+3

+1 для последующего наблюдения – Oli

+0

В чем цель * field.field.widget *, в отличие от использования * field.widget *? – Wipqozn

+0

@Wipqozn в моем опыте 'field.widget' часто ничего не производит - я не уверен в этом, но, возможно, он установлен только в том случае, если вы установите его вручную. 'field.field.widget' работает. – hangtwenty

16

После ответа от Оли и Rinti: Я использовал этот и я думаю, что это немного проще: код

шаблон код {{ field|fieldtype }}

фильтр:

from django import template 
register = template.Library() 

@register.filter('fieldtype') 
def fieldtype(field): 
    return field.field.widget.__class__.__name__ 
Смежные вопросы