2009-11-27 15 views
37

Estoy iterando a través de los campos de un formulario y para ciertos campos quiero un diseño ligeramente diferente, que requiera un código HTML alterado.Obtiene el tipo de widget de formulario de Django desde la plantilla

Para hacer esto con precisión, solo necesito saber el tipo de widget. Su nombre de clase o algo similar. En Python estándar, ¡esto es fácil! field.field.widget.__class__.__name__

Desafortunadamente, no tiene permitido el acceso a las variables de subrayado en las plantillas. ¡Genial!

Usted puede field.field.widget.input_type prueba, pero esto sólo funciona para texto/contraseña <input ../> tipos. Necesito más resolución para eso.

Para mí, por difícil que parezca, tiene más sentido hacer esto a nivel de plantilla. He subcontratado el bit de código que maneja HTML para los campos en una plantilla separada que se incluye en el bucle de campo. Esto significa que es consistente en ModelForm sy en el estándar Form s (algo que no sería cierto si escribiera una clase de formulario intermediario).

Si puede ver un enfoque universal que no me obligue a editar 20 formularios diferentes, ¡hágamelo saber también!

+0

pertinente o función de solicitud: https://code.djangoproject.com/ticket/13009 – Flimm

Respuesta

4

a partir de Django 1.11, sólo puede utilizar widget.input_type. Ejemplo: informe de error

{% 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

¿Cómo hacer una etiqueta de plantilla podría funcionar? Algo así como field.field.widget|widget_type

Edit from Oli: Good point! Acabo de escribir un filtro:

from django import template 
register = template.Library() 

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

Y ahora {{ object|klass }} se representa correctamente. Ahora solo tengo que descubrir cómo usar eso dentro de la declaración if de una plantilla.

Editar desde Oli # 2: Necesitaba usar el resultado de eso en una declaración if en plantilla, así que simplemente cambié toda esa lógica a la plantilla. Magia. Gracias por empujarme en la dirección correcta.

+0

Bienvenido al SO por cierto. – Oli

+1

Gracias por esta solución. Respecto a la Edición # 2 - con las 'if tags' mejoradas en Django 1.2, puede hacer estas comparaciones de tipos de widgets directamente en la plantilla. Publiqué un ejemplo como una respuesta separada. – zlovelady

+1

Otro buen filtro para agregar (si las personas que no son Python manejarán sus plantillas) es algo como esto, para los casos más usados: 'def is_checkboxes (form_field_obj): return (form_field_obj .__ class __.__ name__ ==" CheckboxSelectMultiple ")' ... entonces puedes hacer '{% if field | is_checkboxes%}' y las personas no se asustarán (... no hay devoluciones) – hangtwenty

33

Respondiendo con la respuesta aceptada: el if tag mejorado en Django 1.2 le permite usar filtros en las comparaciones if tag. Por lo que ahora podría hacer su html personalizada/de la lógica en la plantilla de este modo:

<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 de seguimiento – Oli

+0

¿Cuál es el propósito de * field.field.widget *, en lugar de simplemente usar * field.widget *? – Wipqozn

+0

@Wipqozn en mi experiencia 'field.widget' a menudo no produce nada; no estoy seguro de esto, pero tal vez solo esté configurado si lo configura manualmente. 'field.field.widget' funciona. – hangtwenty

16

Tras la respuesta de Oli y Rinti: Solía ​​éste y creo que es un poco más simple: Código

plantilla : código {{ field|fieldtype }}

filtro:

from django import template 
register = template.Library() 

@register.filter('fieldtype') 
def fieldtype(field): 
    return field.field.widget.__class__.__name__ 
Cuestiones relacionadas